3

これは素朴な質問だと確信していますが、ネット上であまり助けが見つからなかったので、それでも質問します. pthreads を使用して C++ コードを書いています。以下は、方法の 1 つの概要です。

void Method1()
{
    try
    {
    pthread_mutex_lock(&syncLock);
    statement1;
    statement2;
    pthread_mutex_unlock(&syncLock);
    statement3;
    statement4;
    }
    catch(exception& e)
    {
    log error
    }
}

ここで、syncLock はタイプpthread_mutex_tであり、デフォルトの初期化を使用して初期化されます。

私の質問は、メソッドの statement2 で例外がスローされた場合、コントロールは直接 catch ステートメントに渡されるということです。その場合、ミューテックスはロックされたままです。ただし、例外がステートメント 3 から発生した場合、ミューテックスはロック解除されており、既にロック解除されているミューテックスで unlock を呼び出すと、未定義の動作が発生するため、単純に catch ブロックに unlock ステートメントを記述することもできません。

したがって、catch ステートメントでミューテックスがロック解除されているかどうかを確認する方法はありますか。または、C++で利用可能なC#スタイルのロックステートメントの代替手段があるので、そのブロック内から例外がスローされた場合でもロックが解放されると確信しています

この目的でライブラリを使用するつもりはありません。シンプルなカスタム ソリューションは大歓迎です

ありがとう

4

2 に答える 2

6

小さな RAII スタイルのロッカー クラスを作成します。

class lock { 
    pthread_mutex_t &mutex;
public:   
    lock(pthread_mutex_t &m) :mutex(m) { pthread_mutex_lock(&mutex); }
    ~lock() { pthread_mutex_unlock(&mutex); }
};

次に、コードを次のように記述します。

void Method1()
{
    try
    {
        { 
            lock l(syncLock);
            statement1;
            statement2;
         }
         statement3;
         statement4;    
    }
    catch(exception& e)
    {
    log error
    }
}

ロックを定義したスコープから出ると、デストラクタを介してロックが破棄され、pthread_mutex_unlock. これは、スコープを正常に終了するか、例外を介して終了するかに関係なく発生します。例外ハンドラに入ると、mutex がロック解除されていることがわかります。

C++11 では、これが標準ライブラリに組み込まれていることに注意してくださいstd::lock_guard(そして、それと一緒に使用する多数のミューテックス型があります)。

于 2013-01-11T06:50:57.047 に答える
1

use pthread_mutex_trylock mutexがすでにロックされている場合は、ビジー状態になります。ロックされていない場合は、ロックされます。この後、ミューテックスのロックを解除します。pthread_mutex_unlock(pthread_mutex_t * mutex);

于 2013-01-11T06:56:17.540 に答える