我试图让一堆生产者线程等待,直到缓冲区有空间容纳某个项目,然后将项目放入缓冲区,如果没有更多空间,则返回睡眠状态。
同时应该有一堆消费者线程等待,直到缓冲区中有东西,然后尽可能地从缓冲区中获取东西,如果缓冲区为空则返回睡眠状态。
在伪代码中,这就是我正在做的事情,但我得到的只是死锁。
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();
}
}
另一个值得一提的错误是,您的消费者仅在缓冲区变空时通知等待的生产者。
仅当队列已满时才通知消费者的最佳方式。
E.g.:
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;
}
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)