std::condition_variable_any:: notify_one
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Member functions | ||||
| Notification | ||||
|
condition_variable_any::notify_one
|
||||
| Waiting | ||||
|
void
notify_one
(
)
noexcept
;
|
(自 C++11 起) | |
如果有任何线程正在等待
*
this
,调用
notify_one
将解除其中一个等待线程的阻塞状态。
注释
notify_one()
/
notify_all()
的效果以及
wait()
/
wait_for()
/
wait_until()
的三个原子操作部分(解锁+等待、唤醒和加锁)发生在一个单一的全序中,该全序可视为原子变量的
修改顺序
:此顺序特定于该条件变量。这使得例如
notify_one()
不可能被延迟,并在
notify_one()
调用完成后才开始等待的线程被解除阻塞。
通知线程不需要持有与等待线程相同的互斥锁;实际上这样做是一种悲观化操作,因为被通知的线程会立即再次阻塞,等待通知线程释放锁。然而,某些实现(特别是pthreads的许多实现)能识别这种情况,通过在通知调用期间将等待线程从条件变量的队列直接转移到互斥锁的队列中而不唤醒它,从而避免这种“匆忙等待”场景。
当需要精确调度事件时,在持有锁期间进行通知可能仍然是必要的,例如,如果等待线程在条件满足时会退出程序,导致通知线程的条件变量被销毁。在互斥锁解锁后但通知前发生虚假唤醒,将导致对已销毁对象调用通知。
示例
#include <chrono> #include <condition_variable> #include <iostream> #include <thread> using namespace std::chrono_literals; std::condition_variable_any cv; std::mutex cv_m; int i = 0; bool done = false; void waits() { std::unique_lock<std::mutex> lk(cv_m); std::cout << "Waiting... \n"; cv.wait(lk, []{ return i == 1; }); std::cout << "...finished waiting; i == " << i << '\n'; done = true; } void signals() { std::this_thread::sleep_for(200ms); std::cout << "Notifying falsely...\n"; cv.notify_one(); // 等待线程在 i == 0 时被通知 // cv.wait 唤醒,检查 i,然后继续等待 std::unique_lock<std::mutex> lk(cv_m); i = 1; while (!done) { std::cout << "Notifying true change...\n"; lk.unlock(); cv.notify_one(); // 等待线程在 i == 1 时被通知,cv.wait 返回 std::this_thread::sleep_for(300ms); lk.lock(); } } int main() { std::thread t1(waits), t2(signals); t1.join(); t2.join(); }
可能的输出:
Waiting... Notifying falsely... Notifying true change... ...finished waiting; i == 1
参阅
|
通知所有等待线程
(公开成员函数) |
|
|
C 文档
关于
cnd_signal
|
|