通知前已完成手动解锁

Dev*_*Dev 6 c++ multithreading

多亏了Scott Meyers医生的书,第263页,我最近发现了condition_variable,所以我不得不按cppreference搜索它以进行更多研究。

https://en.cppreference.com/w/cpp/thread/condition_variable

我对此有几个问题,因为我已经思考了好几天,但我仍然不明白。

我的问题是关于这段代码的:

// Manual unlocking is done before notifying, to avoid waking up
// the waiting thread only to block again (see notify_one for details)
lk.unlock();
cv.notify_one();
Run Code Online (Sandbox Code Playgroud)

1)我不了解cppreference的作者通过该注释和“等待中的线程,只能再次阻止”的含义,因为我什至都不知道如何翻译它,并且

2)它确切地表示哪个线程,特别是为什么。

3)它表示thread_worker还是主线程(父线程)?

4)他们选择这样做吗?

如果作者先通知然后手动解锁,那会发生什么变化?

Pet*_*ker 5

这是次要的,通常是不相关的优化。引起关注的原因是,每个线程在调用互斥对象之后被唤醒notifynotify_all必须锁定互斥对象之后才能继续进行。如果unlocknotify_one(或notify)的调用之后发生,则唤醒的线程将不得不等待,直到调用线程将其解锁。如果对的调用unlock是在通知调用之前进行的,则一个唤醒的线程可以立即获取互斥体。

  • 主线程在条件变量上阻塞,等待工作线程完成。当工作线程完成时,它调用`notify_one`来唤醒主线程。令人担心的是,如果互斥锁不是立即可用的,则主线程可能会带来不便。 (2认同)
  • 虚假的唤醒是完全不同的。允许条件变量释放线程而不调用`notify..l`。这是一个虚假的唤醒,这就是代码通常运行循环的原因:`while(!condition)condition_variable.wait();`。 (2认同)
  • 通过条件变量释放线程时,有两个步骤:唤醒线程和锁定互斥锁。如果互斥锁由于任何原因被锁定,线程将阻塞直到持有锁的线程释放它为止。 (2认同)