std :: lock仍然导致死锁

时间:2017-08-22 15:19:06

标签: c++ c++11 locking deadlock

std :: lock用于防止死锁,对吗?但是在我的测试中,它仍然导致死锁。你能检查我的测试代码,看看我是否错误地使用了它?

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(2));
    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(2));
    std::unique_lock<std::mutex> lock2(m1, std::defer_lock);
    printf("func2 lock m1\n");
    std::lock(m2, m1);
    printf("func2 std lock\n");
}



int _tmain(int argc, _TCHAR* argv[])
{
    std::thread th1(func1);
    std::thread th2(func2);
    th1.join();
    th2.join();
    return 0;
}

输出是: func1锁定m1 func2锁定m2 func2锁定m1 func1锁定m2 func2 std lock

然后控制台挂了......

1 个答案:

答案 0 :(得分:5)

我认为您尝试做的事情不起作用:您无法默默修改唯一锁定下的互斥锁。根据规范,“延迟”构造函数使锁定保护“不拥有”,你不能改变它:

  
unique_lock(mutex_type& m, defer_lock_t) noexcept;
     

效果:构造一个unique_lock类型的对象。

     

后置条件: pm == addressof(m) owns == false

修改仅展示owns变量的唯一方法是对唯一锁定进行操作。独特的锁定不会神奇地检查所保持的互斥锁的状态。

正确的代码应该将唯一锁定传递给std::lock算法:

std::lock(lock1, lock2);