微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法设置条件变量

如何解决无法设置条件变量

在下面的代码中,我在函数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::mutexThis 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_mutexlock开始。 在此期间,线程可能会对try_locklock进行其他调用。当线程对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 举报,一经查实,本站将立刻删除。