Jan*_*net 41 c++ multithreading asynchronous std c++11
当试图回答另一个Stackoverflow问题时,我意识到这个简单的C++ 11片段隐式阻塞了调用线程:
std::async(std::launch::async, run_async_task)
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎是规范的C++ 11方式异步启动任务而不关心结果.相反,为了实现这一点,人们必须明确地创建和分离一个线程(参见上述问题的答案).
所以这是我的问题:关于安全性/正确性,是否有任何理由std::future
必须阻止析构函数?如果它get
仅仅阻止它就不够了,否则,如果我对返回值或异常不感兴趣,它只是火而忘记?
nos*_*sid 32
阻止std :: async和线程返回的期货析构函数:这是一个有争议的话题.以下按时间顺序排列的文件清单反映了委员会成员的一些讨论:
虽然有很多讨论,但是对于std :: future和std :: thread的析构函数的阻塞行为,C++ 14没有计划进行任何更改.
关于你的问题,最有趣的论文可能是Hans Boehm的第二篇.我引用一些部分来回答你的问题.
[..]由归国期货
async()
与async
启动策略等待他们的析构函数相关的共享状态准备就绪.这可以防止关联线程继续运行的情况,并且不再有等待它完成的方法,因为相关的未来已被破坏.如果没有英勇的努力等待完成,这样的"失控"线程可以继续运行它所依赖的对象的生命周期.[例]
最终的结果很可能是一个跨线程的"内存粉碎".如果在[期货]被销毁之前
get()
或被wait()
称为[..] ,当然可以避免这个问题.难点[..]是一个意外的异常可能导致绕过该代码.因此,通常需要某种防护罩以确保安全.如果程序员忘记添加范围保护,则攻击者可能会在适当的时候生成例如bad_alloc异常以利用疏忽,并导致堆栈被覆盖.也可以控制用于覆盖堆栈的数据,从而获得对过程的控制.这是一个非常微妙的错误,根据我们的经验,它可能会在实际代码中被忽略.
更新: Michael Wong的旅行报告还包含一些有关2013年9月会议结果的有趣信息:
关于异步析构函数不应该阻塞的问题,我们就此进行了大量的讨论.[..]获得相当大支持的唯一立场是[...]提供未来析构函数不会阻止的建议,除非从异步中返回,使其成为值得注意的例外.[..]经过重要讨论后,我们尝试携带的唯一部分是N3776,试图澄清除了可能存在异步之外的位置
~future
和~shared_future
不阻止.尝试按照C行发布弃用.不更换时弃用异步.这项动议实际上几乎是提出来的.但[..]它甚至在它到达手术台之前就已经死了.
归档时间: |
|
查看次数: |
7726 次 |
最近记录: |