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 tolock()
,try_lock()
, orunlock()
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 theLockable
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