6

CPPReferenceからstd::mutex、ロックがデッドロックにならない場合、のロック機能がスローされないことが明示的に述べられていません。

PThread のロックにはデッドロック エラーしかありません。ウィンドウのスレッドの実装についてはわかりません。std::thread/のバックエンドとして使用されるスレッドの他の実装であるかどうかもわかりませんstd::mutex

したがって、私の質問は、「特別な理由がなくても、ロックが失敗する場合があるかのようにコードを書く必要がありますか?」です。

実際には、いくつかの noexcept メソッドでミューテックスをロックする必要があり、それらが noexcept であることを確認したいと考えています。

4

3 に答える 3

7

std::mutex::lock()メンバー関数は、c++11 標準 (ドラフト n3337) のnoexceptセクション30.4.1.2 Mutex 型の第 6 節のように宣言されていません。

m.lock()は整形式であり、次のセマンティクスを持つ必要があります。

  • ...
  • スロー:system_error例外が必要な場合 (30.2.2)。
  • エラー条件:
    • operation_not_permitted— スレッドが操作を実行する権限を持っていない場合。
    • resource_deadlock_would_occur— デッドロックが発生することを実装が検出した場合。
    • device_or_resource_busy— ミューテックスがすでにロックされていて、ブロックできない場合。

これは、その関数が例外自体を処理でき、呼び出し元への伝播を防止しない限り、を使用する関数はmutex::lock()マークできないことを意味します。noexcept


これらのエラー状態が発生する可能性についてコメントすることはできませんが、std::mutexand resource_deadlock_would_occur(スローされる可能性がある) に関連して、スレッドが試行した場合にこのエラーstd::mutex発生する可能性があるため、ランタイムの失敗ではなく、コードのバグを示します。すでに所有しているa をロックします。セクション30.4.1.2.1 Class mutex、節 4 から:

[ 注: ミューテックス オブジェクトを所有するスレッドがそのオブジェクトに対して lock() を呼び出すと、プログラムがデッドロックする可能性があります。実装がデッドロックを検出できる場合、resource_deadlock_would_occur エラー状態が観察されることがあります。—終わりのメモ]

ロック タイプとして選択することにより、プログラマは、同じスレッドが既にロックされているスレッドをロックしようとする試みが不可能であることstd::mutexを明示的に示しています。mutexスレッドが a を再ロックする正当な実行パスである場合は、mutexastd:recursive_mutexがより適切な選択です (ただし、a に変更しても、関数に例外recursive_lockがないというわけではありません)。lock()

于 2013-07-09T15:06:47.117 に答える
0

エラー条件(hmjdの回答で概説されている)が存在しないことを保証できる場合、ミューテックスはスローしないと想定しても安全です。その呼び出しを noexcept 関数に入れる方法は、(かなり不可能な)失敗をどのように処理したいかによって異なります。デフォルトの noexcept (to call std::terminate) が受け入れられる場合は、何もする必要はありません。不可能なエラーをログに記録したい場合は、関数を try/catch 句でラップします。

于 2013-07-09T15:30:22.403 に答える