问题描述
查看几个视频和文档示例,我们在调用notify_all()
之前将互斥锁 解锁.改个以后叫它会更好吗?
Looking at several videos and the documentation example, we unlock the mutex before calling the notify_all()
. Will it be better to instead call it after?
常用方法:
在通告程序线程内:
//prepare data for several worker-threads;
//and now, awaken the threads:
std::unique_lock<std::mutex> lock2(sharedMutex);
_threadsCanAwaken = true;
lock2.unlock();
_conditionVar.notify_all(); //awaken all the worker threads;
//wait until all threads completed;
//cleanup:
_threadsCanAwaken = false;
//prepare new batches once again, etc, etc
在其中一个工作线程中:
Inside one of the worker threads:
while(true){
// wait for the next batch:
std::unique_lock<std::mutex> lock1(sharedMutex);
_conditionVar.wait(lock1, [](){return _threadsCanAwaken});
lock1.unlock(); //let sibling worker-threads work on their part as well
//perform the final task
//signal the notifier that one more thread has completed;
//loop back and wait until the next task
}
在通知条件变量之前注意lock2
的解锁方式-我们应该在notify_all()
之后的 之后解锁它吗?
Notice how the lock2
is unlocked before we notify the condition variable - should we instead unlock it after the notify_all()
?
修改
从下面我的评论:我的担心是,如果消费者超级快怎么办.消费者虚假地醒来,看到互斥锁已解锁,完成了任务并循环回到while的开始.现在,缓慢运行的Producer最终调用了notify_all(),从而使使用者循环了额外的时间.
From my comment below: My concern is that, what if consumer is super quick. Consumer spuriously awakes, sees that the mutex is unlocked, completes the task and loops back to the start of while. Now the slow-poke Producer finally calls notify_all(), causing consumer to loop an additional time.
推荐答案
如此处所述: cppreference.com
也就是说,等待文档
一旦通知(明确地,通过其他线程),该函数 解除阻止并调用lck.lock(),使lck处于与when相同的状态 该函数被调用.然后函数返回(注意 最后的互斥锁可能会在返回之前再次阻塞线程.)
Once notified (explicitly, by some other thread), the function unblocks and calls lck.lock(), leaving lck in the same state as when the function was called. Then the function returns (notice that this last mutex locking may block again the thread before returning).
因此,当收到通知等待时,将重新尝试获取该锁,并且在该过程中它将再次被阻塞,直到原始通知线程释放该锁为止.因此,我建议在调用notify之前释放锁.如在cppreference.com上的示例中所做的,最重要的是
so when notified wait will re-attempt to gain the lock and in that process it will get blocked again till original notifying thread releases the lock.So I'll suggest that release the lock before calling notify. As done in example on cppreference.com and most importantly
这篇关于在condition_variable :: notify_all()之后或之前解锁互斥锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!