std::未来等待毁灭
Does std::future wait on destruction
问题std::future在销毁时调用wait()或get()吗?
示例
void fun()
{
std::future<int> fut = my_thread_pool.submit(some_work);
}//is fut.wait() or fut.get() called? here
来源:2013年9月C++标准会议的视图第2部分,共2部分。
关于异步析构函数不应该阻塞的问题,我们用了对此进行了大量讨论相当多的人支持[..]提出未来的自毁装置的建议不会阻塞,除非从async返回,使其成为引人注目的例外[..]经过重要的讨论,我们试图携带N3776,试图澄清~future和~shared_future不阻止,除非可能存在异步的。有人试图以此方式进行抨击C.弃用async而不替换。这个动议实际上几乎提出。但是它甚至在到达手术台。
同时检查:N3679:Async()未来析构函数必须等待
基本问题
异步启动策略等待的异步()返回的期货相关共享状态的析构函数。这防止相关线程继续运行的情况,并且不再有方法等待它完成,因为相关的未来已经被摧毁。没有英勇的努力否则等待完成,这样的"失控"线程可以继续运行超过它所依赖的对象的生存期。
例如,考虑以下两个函数:
void f() { vector<int> v; ... do_parallel_foo(v); ... } void do_parallel_foo(vector<int>& v) { auto fut = no_join_async([&] {... foo(v); return ...; }); a: ... fut.get(); ... }
如果no_join_async()返回其析构函数不等待的future异步完成,一切都可以正常工作,直到a处的代码抛出一个例外。在这一点上,没有任何东西等待异步完成,并且它可能继续从do_paralle_foo()的出口运行和f(),导致异步任务访问并覆盖内存以前分配给v的方式超过了它的生存期。
最终结果可能是类似的跨线程"内存崩溃"在类似的条件下与N2802中描述的相同。
如果调用了get()或wait(),当然可以避免这个问题no_join_async()-在期货被销毁之前生成期货。这个与N2802一样,困难在于意外的异常可能会导致要绕过的代码。因此,某种范围保护通常是需要确保安全。如果程序员忘记添加作用域卫士,攻击者可能会生成例如bad_alloc异常,以利用疏忽,并导致堆栈被覆盖。可能还控制用于覆盖堆栈的数据,从而获得对过程的控制。这是一个非常微妙的错误根据我们的经验,它很可能在实际代码中被忽视。
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 如何让LLDB在成功时退出,在失败时等待
- 等待整个 omp 块完成,然后再调用第二个函数
- 提升 ASIO - io_service 不要等待连接到线程
- 如何在C++中实现带有packaged_task的异步等待循环?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 如何等待窗口隐藏在Qt中?
- 如何在不等待检索的情况下获取C++中的内存位置?
- 等待被迷住了,没有回来
- 等待 WaitForMultipleObjects 窗口中的事件数量可变
- 一个线程等待多个线程事件
- 等待 qthread 终止的正确方法是什么?
- 不可预测的C++睡眠/等待行为
- Bison/flex 在识别规则后等待输入
- 使用记事本C++打开 txt 文件时无需等待
- 接受函数在发送数据包时等待
- 在Visual Studio中运行/调试C ++时,如何在结束时等待输入
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 在等待时破坏condition_variable
- std::未来等待毁灭