c++11 关于 std::condition_variable 的问题

C++语言 码拜 8年前 (2017-04-21) 1136次浏览
先上代码

// 线程函数
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

引用:
Quote: 引用:

这个直接用互斥锁就行吧。发射线程前先加锁,main函数里需要唤醒时解锁。

能写个示例伪代码吗?

// 线程函数
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

引用:
Quote: 引用:

问一下你为什么要 wait?
wait 一般是在等待一个状态,例如初始化结束,例如网络连接,例如计算完成 … 。所以线程内部,首先要检查这个状态,假如已经满足,不需要wait 。不满足时才需要 wait 。其它线程在这个状态变化的时候 notify 。
为了 wait 而 wait ,自然比较奇怪 …

这个wait 就是要等待信号,就好像赛跑比赛,必须枪响了才可以跑,这个wait就是需求决定的

notify 只是指示“枪能否响过了”的状态发生了改变。“枪能否响过了”的状态是记录在另外一个地方的。运动员假如发现枪已经响过了,那他就不用等了。
========================
你的例子了,运动员还没进场(线程还没启动)枪就响了,运动员听不到。但是可以设置一个状态,让运动员虽然听不到,但是依然可以发现枪已经响过了。
========================
或说这里还有另一个等待的问题,即枪必须等运动员准备好之后才能响。运动员必须等枪响之后才能跑。这显然不是一个同步操作(或说一个 wait/notify )能解决的。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明c++11 关于 std::condition_variable 的问题
喜欢 (0)
[1034331897@qq.com]
分享 (0)