async関数launch::asyncポリシーとfutureのちょっと特殊な動作の後日談。
async関数動作でlaunch::asyncポリシーが選択された場合のみ、futureオブジェクトのデストラクタではasync関数が作成した新スレッド完了を待機する。(暗黙的にスレッドjoinが行われる。)
2014-03-15追記:本記事で取りあげたN3451はC++14では却下されている。(→id:yohhoy:20140315)
C++1y(C++14)に向けた提案の中でこの動作仕様を削除、つまり “デストラクタ呼び出しは決してブロックしない” と仕様変更する提案がなされている。(PDF)N3451 async and ~futureより引用。
~future/~shared_future Must Never Block
"Blocking is evil." - Various
Proposed Resolution
Remove the requirement that releasing the shared state of a future spawned by async shall block.
N3451での削除提案は次の3つの観点による。
- Consistency(一貫性):
async
関数の戻り値をローカル変数に代入するか否かで、futureデストラクタが呼ばれるタイミングが変化し動作結果に影響を与える。 - Correctness(正当性):
async(launch::async)
の戻り値をローカル変数で保持しない限り、コードから予測される動作に反して同期的な呼び出しになってしまう。(→id:yohhoy:20120317) - Composability(合成可能性):あるfutureオブジェクト破棄時の挙動を予測できないため、それを用いた大きな処理を組み立てることが困難。
関連URL