异步 Future 中的阻塞析构函数
当从 std::async 返回 future 时,其析构函数会隐式阻塞,从而导致调用线程暂停。虽然这种行为可能看起来令人惊讶,但它是为了安全和正确性而有意为之。
阻止析构函数的原因
正如 Hans Boehm 在白皮书“N3679:异步( ) 未来的析构函数必须等待”,由 async() 返回的 future 等待其关联的共享状态在析构函数中准备就绪。这可以防止出现这样的情况:一旦 future 被销毁,相关线程就会继续运行,而无法等待其完成。如果不采取额外措施,这种“失控”线程可能会超出其依赖对象的生命周期,从而可能导致跨线程“内存崩溃”和安全漏洞。
示例
考虑这个代码片段:
std::future<int> future = std::async(std::launch::async, run_async_task);
如果 future 的析构函数没有阻塞,则线程执行即使 future 被破坏,run_async_task 也可以继续运行。如果此线程访问任何已被销毁的对象,则会发生运行时错误。
替代方法
为了避免阻塞行为,请显式调用 future.get()或 future.wait() 在销毁 future 之前。这确保相关任务已经完成,不再依赖于被破坏的未来。
更新
Michael Wong 在 2013 年 9 月 C 标准会议之后的“旅行报告”提供了有关此主题的最新观点。虽然进行了重要的讨论,但没有对 std::future 析构函数的阻塞行为进行任何更改。此外,一项反对使用异步的提案最终被拒绝。
以上是为什么 std::async() 返回的 Future 具有阻塞析构函数?的详细内容。更多信息请关注PHP中文网其他相关文章!