Scott Meyers氏によるEffective C++11、並行性(Concurrency)関連の目次草案 The View from Aristeia: Draft TOC for EC++11 Concurrency Chapter より抄訳。
- スレッド(thread)ではなく、タスク(task)を作ろう(物理的な"スレッド"ではなく、論理的な"タスク"を使って設計・実装するのが望ましい→id:yohhoy:20120417)
- 非同期処理が必須ならstd::launch::asyncポリシーの指定を(→id:yohhoy:20120203)
- 全ての実行パスでstd::threadをunjoinableにする(確実にjoin/detachを行うべき→id:yohhoy:20120206)
- スレッドハンドルデストラクタの様々な挙動に気を付けよう(→id:yohhoy:20120317)
- void型futureはone-shotイベント通信と考えよう(→id:yohhoy:20120308)
- std::thread, std::async, std::call_onceにはパラメータ無し関数を渡そう(ラムダ式が便利。DECAY_COPY操作での無用なトラブル回避のため?*1→id:yohhoy:20120306)
- 複数ロックの獲得にはstd::lockを用いる(→id:yohhoy:20120919)
- 再帰ミューテックスよりも非再帰版を使おう(無暗にrecursive_mutexを使わず、クラス設計に合わせること。mutexの方が効率的。)
- futureとstd::threadメンバはクラスの最後で宣言しよう(メンバ変数初期化順序に起因するバグ回避のため。)
- try_lock操作, 条件変数の待機, 弱いCAS操作にはspurious failureを考慮したコードを(→id:yohhoy:20120507, id:yohhoy:20120326*2, id:yohhoy:20120725)
- クロック(clock)のsteadyとunsteadyを区別しよう(通常はsteady clockの方が望ましいはず→id:yohhoy:20120717)
- C++11 APIの制約を超えたければネイティブハンドルを使おう(native_handleメンバ関数とネイティブAPIを組合せる。*3)
- できる限り逐次一貫性(sequential consistency)を採用する(std::atomicでは既定メモリオーダー(std::memory_order_seq_cst)の利用を!!*4)
- std::atomicとvolatile変数を区別しよう(必要なのはstd::atomicのはず→id:yohhoy:20121016)
関連URL
*1:Effective C++11: Content and Statusでは"Arguments passed to std::thread, std::async, and std::call_once are unconditionally copied."とされていた。
*2:条件変数の待機(std::condition_variable::wait()など)で直接起こるのはspurious wakeupだが、条件式との組で考えると論理的にはspurious failureと解釈される。
*3:例:スレッド優先度変更やスレッドCPU Affinity Masks指定など。