C++ 调用条件函数时的条件变量? 模板 类阻塞队列{ 私人: 队列(u)队列;; 互斥体(mutex);; 条件变量条件; 公众: 无效推送(常数T和项目){ 唯一的锁柜(互斥锁); _队列。推送(项目); locker.unlock(); _第二,通知某人; } T pop(){ 唯一的锁柜(互斥锁); _cond.wait(locker,[=](){return!_queue.empty();});//lambda函数,按值捕获 T item=_queue.front(); _queue.pop(); 退货项目; } };
这是一个blockingqueue实现。我有两个问题C++ 调用条件函数时的条件变量? 模板 类阻塞队列{ 私人: 队列(u)队列;; 互斥体(mutex);; 条件变量条件; 公众: 无效推送(常数T和项目){ 唯一的锁柜(互斥锁); _队列。推送(项目); locker.unlock(); _第二,通知某人; } T pop(){ 唯一的锁柜(互斥锁); _cond.wait(locker,[=](){return!_queue.empty();});//lambda函数,按值捕获 T item=_queue.front(); _queue.pop(); 退货项目; } };,c++,multithreading,C++,Multithreading,这是一个blockingqueue实现。我有两个问题 在push函数中,在_condnotify_one()之前锁定.unlock();这是必要的,因为当函数返回时,locker超出范围并释放互斥锁。必须在通知之前通知吗 为什么pop()中的条件lambda函数是按值传递的 我不确定我是否遵循了第二个问题,但第一个问题是不,没有必要。如果condvar上有一个活动的服务员,它将收到通知,但不会退出等待,直到互斥锁可用。通常,如果可能的话,您希望像现在这样推送,因为它在互斥上产生的争用较少,但更容
我不确定我是否遵循了第二个问题,但第一个问题是不,没有必要。如果condvar上有一个活动的服务员,它将收到通知,但不会退出等待,直到互斥锁可用。通常,如果可能的话,您希望像现在这样推送,因为它在互斥上产生的争用较少,但更容易与一个以上的侍者发生潜在的虚假唤醒。我认为lambda捕获的是
这个
,而不是\u队列
。因为这是一个指针,按值捕获是合适的。@AlanStokes我相信你是对的。我习惯于使用[这个]
,但我可以肯定地看到您如何描述它的准确性。我相信[=]
隐式地捕获了这个
。建议:保持\u cond.notify\u one()
调用处于锁定状态,唤醒/等待竞争是一件痛苦的事情。@Hasturkun:这是一个误解:互斥锁是关于条件的(queue.empty())。在没有互斥的情况下发送信号没有额外的竞争条件(正如我在类似的讨论中发现的)。另见:
template <typename T>
class BlockingQueue{
private:
queue<T> _queue;
mutex _mutex;
condition_variable _cond;
public:
void push( const T& item){
unique_lock<mutex> locker(_mutex);
_queue.push(item);
locker.unlock();
_cond.notify_one();
}
T pop(){
unique_lock<mutex> locker(_mutex);
_cond.wait(locker, [=](){ return !_queue.empty() ;} ); //lambda function, capture by value
T item = _queue.front();
_queue.pop();
return item;
}
};