Std::Lock 避免了死锁,但这个程序卡住了
Std::Lock avoids deadlock but this program gets stuck
全部,
参考std::lock still caused deadlock
中的问题
我还是想不通下面的代码有什么问题。有人可以解释这个问题以及如何解决这个问题吗?为什么会挂?请帮助。
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
std::mutex m1;
std::mutex m2;
void func1()
{
std::unique_lock<std::mutex> lock1(m1, std::defer_lock);
printf("func1 lock m1\n");
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock2(m2, std::defer_lock);
printf("func1 lock m2\n");
std::lock(m1, m2);
printf("func1 std lock\n");
}
void func2()
{
std::unique_lock<std::mutex> lock1(m2, std::defer_lock);
printf("func2 lock m2\n");
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock2(m1, std::defer_lock);
printf("func2 lock m1\n");
std::lock(m1, m2);
printf("func2 std lock\n");
}
int main(int argc,char* argv[])
{
std::thread th1(func1);
std::thread th2(func2);
th1.join();
th2.join();
return 0;
}
看到的输出:
func1 锁 m1
func2 锁 m2
func1 锁 m2
func1 标准锁
func2 锁 m1
-----挂在这里
即使 func1 已释放两个互斥锁,为什么 func2 不继续?
而不是:
std::lock(m1, m2);
使用:
std::lock(lock1, lock2);
可以在 std::lock
的参考页上找到更多详细信息(包括示例)。
为什么你的代码挂了?
当你调用std::lock(m1, m2)
时,两个互斥量直接被锁定。 std::unique_lock
(lock1
和 lock2
)都不知道这一点,因此他们无法解锁互斥。
因此,当 func1
结束时,两个互斥量仍处于锁定状态,并且 func2
无法继续通过 std::lock(m1, m2)
行。
为什么固定代码有效?
当您调用 std::lock(lock1, lock2)
时,std::unique_lock
(lock1
和 lock2
)知道这一点 - 他们现在拥有锁,并负责解锁他们(当他们超出范围时会发生这种情况)。
因此,当 func1
结束时,两个互斥量都被解锁,并且 func2
可以 继续通过 std::lock(lock1, lock2)
行。一切都很好。
全部, 参考std::lock still caused deadlock
中的问题我还是想不通下面的代码有什么问题。有人可以解释这个问题以及如何解决这个问题吗?为什么会挂?请帮助。
#include <iostream>
#include <mutex>
#include <thread>
using namespace std;
std::mutex m1;
std::mutex m2;
void func1()
{
std::unique_lock<std::mutex> lock1(m1, std::defer_lock);
printf("func1 lock m1\n");
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock2(m2, std::defer_lock);
printf("func1 lock m2\n");
std::lock(m1, m2);
printf("func1 std lock\n");
}
void func2()
{
std::unique_lock<std::mutex> lock1(m2, std::defer_lock);
printf("func2 lock m2\n");
std::this_thread::sleep_for(std::chrono::seconds(1));
std::unique_lock<std::mutex> lock2(m1, std::defer_lock);
printf("func2 lock m1\n");
std::lock(m1, m2);
printf("func2 std lock\n");
}
int main(int argc,char* argv[])
{
std::thread th1(func1);
std::thread th2(func2);
th1.join();
th2.join();
return 0;
}
看到的输出:
func1 锁 m1
func2 锁 m2
func1 锁 m2
func1 标准锁
func2 锁 m1
-----挂在这里
即使 func1 已释放两个互斥锁,为什么 func2 不继续?
而不是:
std::lock(m1, m2);
使用:
std::lock(lock1, lock2);
可以在 std::lock
的参考页上找到更多详细信息(包括示例)。
为什么你的代码挂了?
当你调用std::lock(m1, m2)
时,两个互斥量直接被锁定。 std::unique_lock
(lock1
和 lock2
)都不知道这一点,因此他们无法解锁互斥。
因此,当 func1
结束时,两个互斥量仍处于锁定状态,并且 func2
无法继续通过 std::lock(m1, m2)
行。
为什么固定代码有效?
当您调用 std::lock(lock1, lock2)
时,std::unique_lock
(lock1
和 lock2
)知道这一点 - 他们现在拥有锁,并负责解锁他们(当他们超出范围时会发生这种情况)。
因此,当 func1
结束时,两个互斥量都被解锁,并且 func2
可以 继续通过 std::lock(lock1, lock2)
行。一切都很好。