程序在 C++11 中使用条件变量进入死锁
program went into dead lock using condition variable in c++11
我目前正在尝试学习如何使用 condition_variable
进行线程同步。为了进行测试,我制作了如下所示的演示应用程序。当我启动它时,它遇到了死锁。我知道发生这种情况的位置,但我无法理解为什么会发生死锁。
我知道一个condition_variable
的wait
函数会在条件不为真时自动解锁mutex,所以第二遍应该不会阻塞主线程。但这就是发生的事情。
谁能解释为什么?
#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;
}
您可以通过在 while 循环中移动 unique_lock(...) 语句来解决问题。现在,您正尝试在第 2 轮解锁 lck,但它并未处于锁定状态,因为在第 1 轮之后您再也没有锁定它。
I know that a condition_variable's wait function will automatically unlock the mutex when the condition is not true.
嗯...,是的...,绝对清楚,cv.wait(lck, f)
这样做:
while(! f()) {
cv.wait(lck);
}
并且每次调用 cv.wait(lck)
都会;
- 解锁
lck
,
- 等到其他线程调用
cv.notify_one()
或 cv.notify_all()
,
- 重新锁定
lck
,然后
- return.
我目前正在尝试学习如何使用 condition_variable
进行线程同步。为了进行测试,我制作了如下所示的演示应用程序。当我启动它时,它遇到了死锁。我知道发生这种情况的位置,但我无法理解为什么会发生死锁。
我知道一个condition_variable
的wait
函数会在条件不为真时自动解锁mutex,所以第二遍应该不会阻塞主线程。但这就是发生的事情。
谁能解释为什么?
#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;
}
您可以通过在 while 循环中移动 unique_lock(...) 语句来解决问题。现在,您正尝试在第 2 轮解锁 lck,但它并未处于锁定状态,因为在第 1 轮之后您再也没有锁定它。
I know that a condition_variable's wait function will automatically unlock the mutex when the condition is not true.
嗯...,是的...,绝对清楚,cv.wait(lck, f)
这样做:
while(! f()) {
cv.wait(lck);
}
并且每次调用 cv.wait(lck)
都会;
- 解锁
lck
, - 等到其他线程调用
cv.notify_one()
或cv.notify_all()
, - 重新锁定
lck
,然后 - return.