代码之家  ›  专栏  ›  技术社区  ›  da cheng

在c++11中使用条件变量使程序陷入死锁

  •  0
  • da cheng  · 技术社区  · 7 年前

    我目前正在学习如何使用 condition_variable 用于线程同步。为了进行测试,我制作了如下所示的演示应用程序。当我启动它时,它会陷入死锁。我知道发生这种情况的地点,但我无法理解 为什么? 出现死锁。

    我知道 condition\u变量 wait 当条件不为true时,函数将自动解锁互斥锁,因此主线程不应在第二次传递时被阻塞。但事情就是这样。

    有人能解释一下原因吗?

    #include <thread>
    #include <condition_variable>
    #include <iostream>
    
    bool flag = false;
    std::mutex g_mutex;
    std::condition_variable cv;
    
    
    void threadProc()
    {
        std::unique_lock<std::mutex> lck(g_mutex);
    
        while (true)
        {
            static int count = 0;
    
            std::cout << "wait for flag" << ++count << std::endl;
    
            cv.wait(lck, []() {return flag; }); // !!!It will blocked at the second round
    
            std::cout << "flag is true " << count << std::endl;
    
            flag = false;
            lck.unlock();
        }
    
    }
    
    int main(int argc, char *argv[])
    {
        std::thread t(threadProc);
    
        while (true)
        {
            static int count = 0;
    
            {
                std::lock_guard<std::mutex> guard(g_mutex); // !!!It will blocked at the second round
    
                flag = true;
                std::cout << "set flag " << ++count << std::endl;
            }
    
            cv.notify_one();
    
            std::this_thread::sleep_for(std::chrono::seconds(1));
        }
    
    
        t.join();
    
        return 0;
    }
    
    2 回复  |  直到 7 年前
        1
  •  2
  •   Solomon Slow    7 年前

    我知道,当条件不为true时,condition\u变量的wait函数将自动解锁互斥锁。

    嗯。。。,对我想说清楚, cv.wait(lck, f) 是否:

    while(! f()) {
        cv.wait(lck);
    }
    

    每次呼叫 cv.wait(lck)

    • 解锁 lck ,则,
    • 等待其他线程调用 cv.notify_one() cv.notify_all() ,则,
    • 重新锁定 lck公司 ,然后
    • 回来
        2
  •  1
  •   Leo    7 年前

    您可以通过移动unique\u锁(…)来解决此问题while循环内的语句。现在,您正在尝试解锁第2轮的lck,但它没有处于锁定状态,因为在第1轮之后,您再也没有锁定它。