问题描述
我试图让一堆生产者线程等待,直到缓冲区有空间容纳一个项目,然后在它可以的时候将项目放入缓冲区,如果没有更多空间,则返回睡眠状态.
I am trying to have a bunch of producer threads that wait untill the buffer has room for an item, then it puts items in the buffer while it can, going back to sleep if there is no more room.
同时应该有一堆消费者线程等待直到缓冲区中有东西,然后它可以从缓冲区中取出东西,如果它是空的,则返回休眠.
At the same time there should be a bunch of consumer threads that wait untill there is something in the buffer, then it takes things from buffer while it can, going back to sleep if it's empty.
在伪代码中,这是我在做什么,但我得到的只是死锁.
In pseudo code, here's what Iam doing, but all Iam getting is deadlocks.
condition_variable cvAdd;
condition_variable cvTake;
mutex smtx;
ProducerThread(){
while(has something to produce){
unique_lock<mutex> lock(smtx);
while(buffer is full){
cvAdd.wait(lock);
}
AddStuffToBuffer();
cvTake.notify_one();
}
}
ConsumerThread(){
while(should be taking data){
unique_lock<mutex> lock(smtx);
while( buffer is empty ){
cvTake.wait(lock);
}
TakeStuffFromBuffer();
if(BufferIsEmpty)
cvAdd.notify_one();
}
}
推荐答案
另一个值得一提的错误是您的消费者仅在缓冲区变空时才通知等待的生产者.
One other error worth mentioning is that your consumers only notify the waiting producers when the buffer becomes empty.
只有在队列已满时才通知消费者的最佳方式.
The optimal ways to notify consumers is only when the queue was full.
例如:
template<class T, size_t MaxQueueSize>
class Queue
{
std::condition_variable consumer_, producer_;
std::mutex mutex_;
using unique_lock = std::unique_lock<std::mutex>;
std::queue<T> queue_;
public:
template<class U>
void push_back(U&& item) {
unique_lock lock(mutex_);
while(MaxQueueSize == queue_.size())
producer_.wait(lock);
queue_.push(std::forward<U>(item));
consumer_.notify_one();
}
T pop_front() {
unique_lock lock(mutex_);
while(queue_.empty())
consumer_.wait(lock);
auto full = MaxQueueSize == queue_.size();
auto item = queue_.front();
queue_.pop();
if(full)
producer_.notify_all();
return item;
}
};
这篇关于具有共享缓冲区的两个等待线程(生产者/消费者)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!