如何解决无法设置条件变量
在下面的代码中,我在函数waitingForWork()
中等待条件变量,但是doTheCleanUp()
从未被调用。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex,std::unique_lock
#include <condition_variable> // std::condition_variable
std::mutex mtx;
std::condition_variable cv;
bool stop=false;
void stopTheWait()
{
sleep(5);
printf("stopping the wait.. \n\n");
std::lock_guard<std::mutex> lck(mtx);
stop = true;
cv.notify_all();
}
void doTheCleanUp()/* is never called*/ {
printf("clean up... \n\n");
}
void waitingForWork(){
printf("wait for ever... \n\n");
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck,[]{ return stop;});
doTheCleanUp();
printf("clean Up Done,Now end wait... \n\n");
}
int main()
{
printf("in main... \n");
std::unique_lock<std::mutex> lck(mtx);
std::thread t1(stopTheWait);
waitingForWork();
printf("exiting main...\n");
sleep(1);
return 0;
}
解决方法
main()
正在锁定std::mutex
,然后在同一线程中调用waitingForWork()
,该线程试图再次锁定std::mutex
。 This is undefined behavior:
如果已经拥有互斥锁的线程调用
lock
,则行为未定义:例如,程序可能会死锁。鼓励可以检测到无效用法的实现抛出具有错误条件std::system_error
的{{1}}而不是死锁。
resource_deadlock_would_occur
没有充分的理由获得该初始锁,并摆脱它:
main()
请注意,通常,如果必须在同一线程中多次锁定互斥锁,则需要改用std::recursive_mutex
:
一个调用线程拥有一个
int main() { printf("in main... \n"); //std::unique_lock<std::mutex> lck(mtx); // <-- HERE std::thread t1(stopTheWait); waitingForWork(); printf("exiting main...\n"); sleep(1); return 0; }
一段时间,从成功调用recursive_mutex
或lock
开始。 在此期间,线程可能会对try_lock
或lock
进行其他调用。当线程对try_lock
进行匹配的调用次数时,所有权期限结束
还请注意,您需要在unlock
超出范围并被销毁之前调用t1.join()
或t1.detach()
,否则其destructor将异常终止调用过程:
,如果
t1
具有关联的线程(*this
),则调用std::terminate()
。
您在这里有一个错误:
void waitingForWork(){
printf("wait for ever... \n\n");
std::unique_lock<std::mutex> lck(mtx); // This lock is bad.
// you already locked the
// mutex in main.
//
// locking it again is UB
cv.wait(lck,[]{ return stop;}); // Once you enter wait()
// lock will be released
// until you are notified.
doTheCleanUp();
printf("clean Up Done,now end wait... \n\n");
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。