// 线程函数 void ThreadFunction(int iID, std::mutex& Lock, std::condition_variable& rStart) { std::unique_lock<std::mutex> unqLock(Lock); rStart.wait(unqLock); printf("Thread ID=%c\n","A"+iID); } // 主函数 int _tmain(int argc, _TCHAR* argv[]) { std::mutex Lock; std::condition_variable con; std::future<void> thd=std::async(std::launch::async,ThreadFunction,0,std::ref(Lock),std::ref(con)); con.notify_one(); thd.wait(); }
程序设计是这样的,当主线程发起通知,线程函数就打印本人的线程ID
也就是线程创建完毕之后线程函数在 rStart.wait(unqLock); 处等待通知,当主线程执行 con.notify_one(); 开始打印。
但是现在有个问题,当 con.notify_one(); 的时候假如没有任何等待则通知不起任何作用,要命的是程序执行起来根本无法保证 rStart.wait(unqLock); 在 con.notify_one(); 之前运行,这就造成一个结果,调用了通知可是子线程还是被block了。
有没有什么方法能够像 Windows API 的 Event 那样,即使没有 WaitForSingleObject 等待 SetEvent 也能起作用的方法呢?
80
// 线程函数 void ThreadFunction(int iID, std::mutex &my_mutex) { std::lock_guard<std::mutex> lock(my_mutex); printf("Thread ID=%c\n","A" + iID); } // 主函数 int main() { std::mutex my_mutex; my_mutex.lock(); std::future<void> thd = std::async(std::launch::async, ThreadFunction, 0, std::ref(lock)); my_mutex.unlock(); thd.wait(); }
这样?
20
问一下你为什么要 wait?
wait 一般是在等待一个状态,例如初始化结束,例如网络连接,例如计算完成 … 。所以线程内部,首先要检查这个状态,假如已经满足,不需要wait 。不满足时才需要 wait 。其它线程在这个状态变化的时候 notify 。
为了 wait 而 wait ,自然比较奇怪 …这个wait 就是要等待信号,就好像赛跑比赛,必须枪响了才可以跑,这个wait就是需求决定的
notify 只是指示“枪能否响过了”的状态发生了改变。“枪能否响过了”的状态是记录在另外一个地方的。运动员假如发现枪已经响过了,那他就不用等了。
========================
你的例子了,运动员还没进场(线程还没启动)枪就响了,运动员听不到。但是可以设置一个状态,让运动员虽然听不到,但是依然可以发现枪已经响过了。
========================
或说这里还有另一个等待的问题,即枪必须等运动员准备好之后才能响。运动员必须等枪响之后才能跑。这显然不是一个同步操作(或说一个 wait/notify )能解决的。