notify_all() 之后和 wait() 获得锁之前发生了什么?
what happen between after notify_all() and before wait() get the lock?
我使用以下代码测试 std::condition_variable
:
class CondWait{
public:
std::condition_variable cv;
std::mutex mu;
int i=0;
public:
void mainTask(){
std::unique_lock<std::mutex> lk(mu);
cv.wait(lk);
i++;
std::cout<<"main task, "<<i<<std::endl;
}
void notifyTask(){
std::unique_lock<std::mutex> lk(mu);
i = 0;
std::cout<<"notify task, "<<i<<std::endl;
cv.notify_one();
std::cout<<"notify task, sleep 5 sec"<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
}
};
int main()
{
CondWait condwait;
std::thread t1(&CondWait::mainTask,&condwait);
std::thread t2(&CondWait::notifyTask,&condwait);
t1.join();
t2.join();
return 0;
}
有时,输出如下,程序被阻塞:
notify task, 0
notify task, sleep 5 sec
有时,程序会 运行 很好,即休眠5秒后,会输出main task, 1
,完整的输出为:
notify task, 0
notify task, sleep 5 sec
main task, 1
在我看来,在notifyTask
线程中,在notify_one
之后仍然使用互斥量,所以mainTask
中的wait
无法锁定互斥量。但是不知道接下来会发生什么,为什么这个例子会有歧义的表现。你能提供一些建议吗?非常感谢!
由于您同时启动了两个线程,可能会出现这样的情况,即在 mainTask
中的 cv.wait()
之前调用 cv.notify_one()
并且由于还没有线程在等待,函数 什么都不做。之后,wait()
被执行并挂起等待通知
我使用以下代码测试 std::condition_variable
:
class CondWait{
public:
std::condition_variable cv;
std::mutex mu;
int i=0;
public:
void mainTask(){
std::unique_lock<std::mutex> lk(mu);
cv.wait(lk);
i++;
std::cout<<"main task, "<<i<<std::endl;
}
void notifyTask(){
std::unique_lock<std::mutex> lk(mu);
i = 0;
std::cout<<"notify task, "<<i<<std::endl;
cv.notify_one();
std::cout<<"notify task, sleep 5 sec"<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(5));
}
};
int main()
{
CondWait condwait;
std::thread t1(&CondWait::mainTask,&condwait);
std::thread t2(&CondWait::notifyTask,&condwait);
t1.join();
t2.join();
return 0;
}
有时,输出如下,程序被阻塞:
notify task, 0
notify task, sleep 5 sec
有时,程序会 运行 很好,即休眠5秒后,会输出main task, 1
,完整的输出为:
notify task, 0
notify task, sleep 5 sec
main task, 1
在我看来,在notifyTask
线程中,在notify_one
之后仍然使用互斥量,所以mainTask
中的wait
无法锁定互斥量。但是不知道接下来会发生什么,为什么这个例子会有歧义的表现。你能提供一些建议吗?非常感谢!
由于您同时启动了两个线程,可能会出现这样的情况,即在 mainTask
中的 cv.wait()
之前调用 cv.notify_one()
并且由于还没有线程在等待,函数 什么都不做。之后,wait()
被执行并挂起等待通知