6

2 つの boost::scoped_locks を同時に保持すると問題が発生するかどうかを知りたいです。ロックは異なるミューテックスをロックしています。次の例を検討してください。

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

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

これがデッドロックを引き起こすべきではないことを私は知っています。しかし、他に問題はありますか。これにより、スレッドが長時間スリープ状態になる可能性がありますか?

4

2 に答える 2

7

これにより、誰かが両方のミューテックスを逆の順序で取得すると、デッドロックが発生する可能性があります。

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

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

次のように 2 つのスレッドがインターリーブされると、デッドロックが発生します。

                                 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基盤となるOSはそうかもしれませんが、これがこれに対する保護を提供するとは思いません。

于 2016-07-20T19:36:51.173 に答える
6

複数のロックを保持すること自体は問題ではありません。

他のスレッドが同じロックを別の順序で取得しようとすると、問題が発生し、ABBAデッドロックが発生します。スレッド 1 がロックAし、次にBスレッド 2 がロックしようとすると、両方がブロックされてしまいます (ロックがインターリーブされている場合、 t1 がロックし、次に t2 がロックし、両方がブロックして他方をロックしようとします)、他方がロックの 1 つを解放するのを待ちます。続行できるようにするため (そして、他の人が続行できるようにする独自の保持されたロックを解放するため)。BAAB

したがって、一般的な経験則は次のとおりです。複数のロックを取得する必要がある場合は、すべてのスレッドが常に同じ順序でそれらのロックを取得しようとすることを確認してください。

于 2016-07-20T19:36:33.640 に答える