4

私はブースト ライブラリを初めて使用しましたが、これは素晴らしいライブラリです。また、私はミューテックスを初めて使用するので、初心者の間違いを犯している場合はご容赦ください。

とにかく、 と という 2 つの関数がFunctionOneありFunctionTwoます。別のスレッドによって非同期的に呼び出されますFunctionOneFunctionTwoではFunctionOne、関数の最初でグローバル ミューテックスをロックし、関数の最後でグローバル ミューテックスをロック解除します。についても同じですFunctionTwo

ここに問題があります:FunctionOneFunctionTwoが数ミリ秒以内に呼び出されることがあります (常にではありません)。したがって、FunctionOne実行を開始し、途中でFunctionTwo実行します。がミューテックスをロックすると、 とがオンになっているFunctionTwo スレッド全体が停止するため、途中でスタックし、スレッドは永久に待機します。要約すると、次のようになります。FunctionOneFunctionTwoFunctionOneFunctionTwo

  • 関数 1 はミューテックスをロックし、コードの実行を開始します。
  • 関数 2 は数ミリ秒後に呼び出されてミューテックスをロックし、関数 1 と 2 がオンになっているスレッドをフリーズします。
  • func 1 が途中でスタックし、スレッドがフリーズしたため、func 1 は決して終了せず、mutex は永久にロックされ、func 1 が終了するのを待ちます。

そのような状況で何をしますか?これが私のコードです:

boost::mutex g_Mutex;
lua_State* L;

// Function 1 is called from some other thread
void FunctionOne()
{
    g_Mutex.lock();

    lua_performcalc(L);

    g_Mutex.unlock();
}

// Function 2 is called from some other thread a few ms later, freezing the thread
// and Function 1 never finishes
void FunctionTwo()
{
    g_Mutex.lock();

    lua_performothercalc(L);

    g_Mutex.unlock();
}
4

2 に答える 2

8

これらの関数は、ミューテックスを保持している間に FunctionOne がそれ自体または FunctionTwo を呼び出すように、再入可能であることを意図していますか? またはその逆で、FunctionTwo がミューテックスをロックし、ミューテックスがロックされている間に FunctionOne/FunctionTwo を呼び出しますか?

  • そうでない場合は、これら 2 つの関数を同じスレッドから呼び出すべきではありません。FunctionOne が完了するまで FunctionTwo をブロックするつもりなら、それを同じスレッドで呼び出すのは誤りです。これは、lua_performcalc が FunctionTwo を呼び出した場合に発生します。それが同じスレッドで呼び出される唯一の方法です。

  • もしそうなら、recursive_mutexが必要です。通常のミューテックスは一度しかロックできません。同じスレッドから再度ロックするとエラーになります。再帰的ミューテックスは、1 つのスレッドで複数回ロックでき、スレッドがロック解除を同じ回数呼び出すまでロックされます。

どちらの場合でも、lock と unlock を明示的に呼び出すことは避けてください。例外がスローされた場合、ミューテックスはロック解除されません。次のように、RAII スタイルのロックを使用することをお勧めします。

{
    boost::recursive_mutex::scoped_lock lock(mutex);

    ...critical section code...

    // mutex is unlocked when 'lock' goes out of scope
}
于 2012-12-10T17:46:22.530 に答える
3

あなたの説明は間違っています。ミューテックスを 2 回ロックすることはできません。あなたは別の問題を抱えています。

  • ミューテックスがロックされている間の再入をチェックします。
  • 例外をチェックする

使用すべき例外に関する問題を回避するためにboost::mutex::scoped_lock( RAAI )

于 2012-12-10T17:59:41.777 に答える