您需要存储std::async的std::future返回值吗



考虑以下代码:

#include <iostream>
#include <future>
#include <thread>
#include <chrono>
void func()
{
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
}
int main()
{
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "msn";
func();
std::cout << "stop  " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "msn";
return 0;
}

输出:

start 18737230ms
stop  18738230ms

我们可以看到,在func()返回之前已经过了1秒。但是,没有从std::async(...);存储std::future,即:auto f = std::async(...)

这似乎是有效的,但我在想这是什么机制起作用。如果我有一个std::future(在我的小例子中是auto f(,那么当它超出范围时,它会整理线程——即等待1秒,然后在幕后处理线程。

进一步测试:

int main() {
std::cout << "start " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "msn";
std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop1 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "msn";
auto f = std::async(std::launch::async, []{std::this_thread::sleep_for(std::chrono::milliseconds(1000)); });
std::cout << "stop2 " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "msn";
return 0;
}

给出:

start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed

因此,这表明存储未来,意味着线程并行运行。不存储未来意味着线程似乎必须运行到完成——我想这是因为创建并销毁了一个临时的未来?

所以我的结论是,如果你想让它并行运行(这就是重点(,即使你不打算使用future,你也不能只调用std::async(...)而不存储std::future。

嗯。。。我想我刚刚说服了自己答案!-但我不能100%确定我的推理是正确的——希望我。。。

如果std::future是通过std::async创建的,则析构函数将等待任务结束。这并不意味着任务不并行运行——它只是在变量范围的末尾等待任务的结束。然而,在不存储std::future的情况下使用std::async有点棘手,我通常建议将未来存储在某个地方,以避免令人讨厌的意外。看看关于std::future析构函数(强调矿(的页面:

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

相关内容

  • 没有找到相关文章

最新更新