异步C++11中未来的析构函数

Destructor of a future in async C++11

本文关键字:析构函数 未来 C++11 异步      更新时间:2023-10-16

编译器是否应该在main完成后立即调用未来future的析构函数,也就是说,无论如何都不应该调用函数f()?(gcc 4.7.2没有这么做)。

#include <iostream>
#include <thread>
#include <future>
using namespace std;
void f() {
cout << "thread...n";
}
int main() {
auto future = async(&f);
cout << "I am mainn";
}

编辑:我只得到Hello from main。文本thread...根本没有打印出来。

edit2:未来的析构函数是否调用wait()??

注意:下面是过时的信息(C++14之前)有关最新信息,请参阅Jonas的回答。


编译器不应该在主完成之后立即调用未来的析构函数

main完成之前右。但是是的。

也就是说,函数f()无论如何都不应该被调用吗?

不,为什么?是什么让你认为std::future的析构函数会这么做?这不是析构函数的工作。事实上,根据§30.6.6/9,析构函数的唯一功能是释放未来的共享状态并销毁*this。没什么了。

这是未来演讲(双关语):

FWIW,Konrad的答案只适用于C++11。在C++14中,这种行为发生了改变。根据cppreference:

这些操作不会阻止共享状态变为就绪,但如果以下所有情况都为真,则它可能会阻止:共享状态是通过调用std::async创建的,共享状态还不是就绪,这是对共享状态的最后一次引用。

尽管上面的报价没有提到启动策略,但我只能在异步启动任务的情况下确认这种行为。根据我的测试,从未明确等待过的std::async(std::launch::deferred, ...)创建的未来似乎不会在未来被破坏时得到评估。

还需要注意的是,这只适用于从std::async创建的期货,因此在很大程度上不是额外的wait();被打到std::future的析构函数上的情况。

最后,截至Boost 1.73,当由boost::async(boost::launch::async, ...)创建时,boost::future的类似变化是而不是,即Boost版本的行为仍然与std::future在C++14之前的行为相同。