非同期 Future でのブロックされたデストラクター
Future が std::async から返されると、そのデストラクターは暗黙的にブロックされ、呼び出しが行われます。スレッドが一時停止しています。この動作は意外に思えるかもしれませんが、安全性と正確性を考慮して意図的に行われています。
デストラクターをブロックする理由
ホワイトペーパー「N3679: Async(」で Hans Boehm が述べているように) 将来のデストラクターは待機する必要があります。」 async() によって返される将来は、関連する共有状態がデストラクターで準備完了になるまで待機します。これにより、フューチャーが破棄された後、関連付けられたスレッドがその完了を待つ方法なしに実行を継続するというシナリオが回避されます。追加の対策を講じないと、このような「暴走」スレッドは依存オブジェクトの存続期間を超えて拡張され、スレッド間の「メモリ スマッシュ」やセキュリティの脆弱性を引き起こす可能性があります。
例
次のコード スニペットを考えてみましょう:
std::future<int> future = std::async(std::launch::async, run_async_task);
Future のデストラクターがブロックしていない場合、run_async_task を実行しているスレッドは Future が破棄された後でも実行を続けることができます。このスレッドが既に破棄されたオブジェクトにアクセスすると、ランタイム エラーが発生します。
代替アプローチ
ブロック動作を回避するには、明示的に future.get() を呼び出します。または、future を破棄する前に future.wait() を実行します。これにより、関連付けられたタスクが完了し、破壊された未来に依存しなくなります。
更新
2013 年 9 月の C 標準会議後の Michael Wong の「旅行レポート」は、このトピックに関する最新の視点を提供します。重要な議論はありましたが、std::future デストラクターのブロック動作に対する変更は行われませんでした。さらに、非同期の使用を非推奨にするという提案は最終的に拒否されました。
以上がstd::async() によって返される Future にブロッキング デストラクターがあるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。