lock_guard 和queue 设计一个存放图像的队列,一个线程读图,一个线程取图
时间: 2024-10-01 17:07:20 浏览: 32
为了设计一个使用 `lock_guard` 和 `queue` 存放图像的线程安全队列,我们可以创建一个名为 `ImageQueue` 的类,其中包含一个 `std::queue` 用于存储图像指针,以及两个互斥锁来确保读取和写入操作的同步。这样,一个线程可以负责从队列中取出图像(`pop_image`),而另一个线程负责往队列中放入新的图像(`enqueue_image`)。这里是一个基本的 C++ 实现:
```cpp
#include <queue>
#include <mutex>
#include <condition_variable>
class Image {
public:
int id;
// 图像数据...
Image(int id) : id(id) {}
};
class ImageQueue {
private:
std::queue<Image*> images;
mutable std::mutex read_lock; // 用于读取操作
mutable std::mutex write_lock; // 用于写入操作
std::condition_variable image_available;
public:
void enqueue_image(Image* img) {
std::unique_lock<std::mutex> lock(write_lock);
images.push(img);
image_available.notify_one(); // 唤醒等待的读者
}
std::optional<Image*> pop_image() {
std::unique_lock<std::mutex> lock(read_lock);
while (images.empty()) {
image_available.wait(lock); // 阻塞并等待有新图片
}
Image* img = images.front();
images.pop();
return img; // 返回图像,如果有的话
}
};
int main() {
ImageQueue queue;
std::thread reader_thread([&]() {
for (;;) {
auto img = queue.pop_image();
if (!img) {
// 队列为空,结束循环
break;
}
// 处理图片...
}
});
std::thread writer_thread([&]() {
for (int i = 1; i <= 10; ++i) {
Image* img = new Image(i);
queue.enqueue_image(img); // 使用write_lock保证插入顺序
delete img; // 注意释放内存
}
// 写入结束后通知reader_thread停止
queue.enqueue_image(nullptr);
});
reader_thread.join();
writer_thread.join();
return 0;
}
```
在这个示例中,`enqueue_image` 通过 `write_lock` 保证只有写入操作能修改队列,而 `pop_image` 则通过 `read_lock` 读取队列。当 `enqueue_image` 完成后,它会唤醒等待在 `image_available` 上的 `pop_image`。`pop_image` 循环读取队列,直到队列为空为止。
阅读全文