yohhoyの日記

技術的メモをしていきたい日記

lock非メンバ関数の使いどころ

C++11標準ライブラリやBoost.Threadライブラリで提供される、複数ロック操作lockメンバ関数の適用先についてメモ。

lockメンバ関数の仕様上、ロック競合しうる複数ミューテックスを指定してもデッドロック(deadlock)しない。この関数の内部実装には try-and-back-off アルゴリズム等が用いられるが、論理的にはライブロック(livelock)によるリソーススタべーション(resource starvation)のリスクがあることに注意。実効上問題になるケースは少ないと思われるが、特に高ロック競合(contention)が生じる場合は無視できない可能性あり。

ロック獲得戦略は下記に従うのが望ましい:

  • ロック順序(ロック階層)を静的に決定できる場合は、その順序に従ったロック獲得操作を行う。lockメンバ関数の利用は避ける。
  • アプリケーション設計によってロック順序を決定できない場合は、lockメンバ関数を利用する。

N3337 30.4.3/p5より一部引用。

template <class L1, class L2, class... L3> void lock(L1&, L2&, L3&...);
5 Effects: All arguments are locked via a sequence of calls to lock(), try_lock(), or unlock() on each argument. The sequence of calls shall not result in deadlock, but is otherwise unspecified. [Note: A deadlock avoidance algorithm such as try-and-back-off must be used, but the specific algorithm is not specified to avoid over-constraining implementations. -- end note] (snip)

Boost.Thread 1.51.0ドキュメントより一部引用。

Effects:
Locks the Lockable objects supplied as arguments in an unspecified and indeterminate order in a way that avoids deadlock. It is safe to call this function concurrently from multiple threads with the same mutexes (or other lockable objects) in different orders without risk of deadlock. (snip)

関連URL