std :: lock仍然导致死锁

til*_*man 4 c++ deadlock locking c++11

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;
}
Run Code Online (Sandbox Code Playgroud)

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

然后控制台挂...

Ker*_* SB 5

我认为你要做的事情不起作用:你不能默默地修改唯一锁下面的互斥锁.根据规范,"延迟"构造函数使锁定保护"不拥有",你不能改变:

unique_lock(mutex_type& m, defer_lock_t) noexcept;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

std::lock(lock1, lock2);
Run Code Online (Sandbox Code Playgroud)