同时拿着两个互斥锁

时间:2016-07-20 19:25:10

标签: c++ thread-safety mutex boost-mutex

如果我同时持有两个boost :: scoped_locks,我想知道是否会有任何问题。锁定锁定不同的互斥锁。请考虑以下示例:

void foo1()
{
   boost::recursive_mutex::scoped_lock lock(mutex1);
   foo2();
}

void foo2()
{
   boost::recursive_mutex::scoped_lock lock(mutex2);
}

我知道这不应该导致死锁。但是还有其他问题吗?也许这会导致线程长时间睡眠?

2 个答案:

答案 0 :(得分:6)

如果有人以相反的顺序同时获取这两个互斥锁,则 会导致死锁。

void bar1() {
    boost::recursive_mutex::scoped_lock lock(mutex2);
    bar2();
}

void bar2() {
    boost::recursive_mutex::scoped_lock lock(mutex1);
}

如下交错的两个线程将死锁:

                                 mutex1  mutex2
Time    Thread A     Thread B    owner   owner
  0     foo1()                     A
  1                  bar1()        A       B
  2                  bar2()        A       B
  3     foo2()                     A       B

此时线程A& B陷入僵局。虽然基础操作系统可能会boost提供保护,但我不认为import org.apache.tools.ant.taskdefs.condition.Os ... android { ... sourceSets.main { jniLibs.srcDir 'src/main/libs' //set libs as .so's location instead of jniLibs jni.srcDirs = [] //disable automatic ndk-build call with auto-generated Android.mk } // call regular ndk-build(.cmd) script from app directory task ndkBuild(type: Exec) { if (Os.isFamily(Os.FAMILY_WINDOWS)) { commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath } else { commandLine 'ndk-build', '-C', file('src/main').absolutePath } } tasks.withType(JavaCompile) { compileTask -> compileTask.dependsOn ndkBuild } }

答案 1 :(得分:5)

持有多个锁本身本身是一个问题。

当其他线程尝试以不同的顺序获取相同的锁并且最终导致ABBA死锁时,会出现问题。线程1锁定AB,然后线程2想要锁定B然后A并且最终都被阻塞(如果锁定交错,那么t1锁定{{1} },然后t2锁定A,然后两个阻止尝试锁定另一个)等待另一个释放其中一个锁,以便能够继续(并释放他们自己的持有锁,这将允许另一个继续)。

所以,一般的经验法则是;如果你需要获得多个锁,请确保所有线程总是尝试以相同的顺序获取这些锁。