Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用c+;中的条件变量,程序进入死锁状态+;11_C++_Multithreading_C++11_Mutex_Condition Variable - Fatal编程技术网

C++ 使用c+;中的条件变量,程序进入死锁状态+;11

C++ 使用c+;中的条件变量,程序进入死锁状态+;11,c++,multithreading,c++11,mutex,condition-variable,C++,Multithreading,C++11,Mutex,Condition Variable,我目前正在尝试学习如何使用条件变量进行线程同步。为了进行测试,我制作了如下所示的演示应用程序。当我启动它时,它会进入死锁。我知道发生这种情况的位置,但我无法理解为什么会发生死锁 我知道当条件为非真时,condition\u变量的wait函数将自动解锁互斥锁,因此主线程不应在第二次传递时被阻塞。但事情就是这样 有人能解释为什么吗 #include <thread> #include <condition_variable> #include <iostream>

我目前正在尝试学习如何使用
条件变量
进行线程同步。为了进行测试,我制作了如下所示的演示应用程序。当我启动它时,它会进入死锁。我知道发生这种情况的位置,但我无法理解为什么会发生死锁

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

有人能解释为什么吗

#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;
}
#包括
#包括
#包括
布尔标志=假;
std::mutex g_mutex;
std::条件变量cv;
void threadProc()
{
std::唯一锁lck(g_互斥);
while(true)
{
静态整数计数=0;

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

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

我知道当条件为非真时,条件变量的wait函数将自动解锁互斥锁

嗯…,是的…,只是为了绝对清楚,
cv.wait(lck,f)
这样做:

while(! f()) {
    cv.wait(lck);
}
每次调用
cv.wait(lck)
都将:

  • 解锁
    lck
  • 等待其他线程调用
    cv.notify\u one()
    cv.notify\u all()
  • 重新锁定
    lck
    ,然后
  • 返回
我知道当条件为非真时,条件变量的wait函数将自动解锁互斥锁

嗯…,是的…,只是为了绝对清楚,
cv.wait(lck,f)
这样做:

while(! f()) {
    cv.wait(lck);
}
每次调用
cv.wait(lck)
都将:

  • 解锁
    lck
  • 等待其他线程调用
    cv.notify\u one()
    cv.notify\u all()
  • 重新锁定
    lck
    ,然后
  • 返回

hmm,这不仅仅是锁,它在那一点上对我来说崩溃了是的,我的构建环境是VS2017。然后我在叮当声中尝试,它崩溃并提升解锁处于解锁状态的互斥体。hmm,这不仅仅是锁,它在那一点上对我来说崩溃了是的,我的构建环境是VS2017。然后我在叮当声中尝试,它崩溃并提升解锁处于解锁状态的互斥体的互斥体解锁状态。谢谢。你的意思是当cv.wait在第二轮时,cv.wait发现条件为假,然后cv.wait尝试解锁lck,但lck本身处于解锁状态,然后它被阻止或某种崩溃。是的,这就是我的意思。谢谢。你的意思是当cv.wait在第二轮时,cv.wait发现条件为假,然后cv.wait尝试解锁lck,但lck自身处于解锁状态,然后它被阻止或某种崩溃。是的,这就是我的意思。谢谢。另一个问题,如果它在步骤1中解锁lck,它如何确保步骤2中的等待功能在来自其他线程的通知之前生效?谢谢。另一个问题,如果它在步骤1中解锁lck,它如何确保等待步骤2中的函数将在通知其他线程之前生效?