使用通知全部进行多次等待
Multiple wait using notify all
我希望在等待中使用条件变量。
我创建了一个包含 10 个线程的程序,每个线程等待来自主线程的信号notify_all()
。但它陷入僵局,我不想理解为什么。
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <chrono>
using namespace std;
std::mutex mtx;
std::condition_variable cv;
int xx = 0;
void print_id (int id) {
std::unique_lock<std::mutex> lck(mtx);
cout<<"Start thread id " << id << " n";
for(int i=0; i<9; i++)
{
cout<<"Thread " << id << " i " << i <<"n";
cv.wait(lck);
}
}
void go()
{
cv.notify_all();
for(int i=0; i<10; i++)
{
//Some works for threads
cv.notify_all();
}
}
int main ()
{
std::thread threads[10];
for (int i=0; i<10; ++i)
threads[i] = std::thread(print_id,i);
std::cout << "10 threads ready to race...n";
go(); // go!
for (auto& th : threads) th.join();
}
这不是条件变量的工作方式。
要认识到的主要事情是,条件变量本身不能可靠地发出事件信号。特别是,wait()
呼叫可能会虚假返回,也就是说,没有人呼叫notify
。
相反,您需要的是条件变量绑定到的周围程序中的逻辑条件。只要条件更改,就可以调用通知,并通过提供检查器谓词函数作为调用的参数来检查条件,wait
作为周围循环的一部分或在wait
内部检查条件。
另一个需要注意的问题是,虽然等待不能在没有通知的情况下继续(从逻辑上讲,假设没有虚假的唤醒(,但相反的情况并非如此。也就是说,go()
函数甚至可以在print_id
函数到达第一个等待之前运行完成。然后,该等待将被永久阻止,因为途中不再有通知。通知不要等待等待,它们是即发即弃操作。
在正确使用条件变量时,这不是问题,因为等待只是等待逻辑条件更改。如果该更改已在等待调用之前发生,则您检测到它,并且首先不要调用等待。
您可能在这里想要的是障碍的行为。您可以使用int
计数器作为条件以及同步condition_variable
和mutex
,轻松实现自己的屏障。
相关文章:
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 如何让LLDB在成功时退出,在失败时等待
- 函数如何通知用户它基于函数原型抛出异常?
- 等待整个 omp 块完成,然后再调用第二个函数
- 如何在ECS框架中更新组件数据和通知系统
- 当 I2C 值在C++中发生变化时收到通知
- 提升 ASIO - io_service 不要等待连接到线程
- 使用通知全部进行多次等待
- 如何修复条件变量等待/通知的竞争条件
- 反应任务在检测任务通知之前等待
- 当在其他地方使用相同的互斥锁时,等待/通知unique_lock互斥锁是否安全lock_guard
- 是我的等待 - 使用std :: mutex通知机制正确
- 等待通知pthreads unix C++
- 为什么既有std :: condition_variaible的通知和等待功能,都需要锁定的静音
- 条件变量 - 等待/通知种族条件
- std::condition_variable - 等待多个线程通知观察者
- 视觉提升 条件变量中的同步队列C++不通知其他线程上的等待类方法
- 面向通知-等待模式的c++多线程算法设计
- 在c++中等待通知
- std::condition_variable – 通知一次,但等待线程唤醒两次