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中的函数将在通知其他线程之前生效?