cod*_*der 3 c++ c++11 stdasync
考虑以下代码:
#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() << "ms\n";
func();
std::cout << "stop " << std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count() << "ms\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
start 18737230ms
stop 18738230ms
Run Code Online (Sandbox Code Playgroud)
我们可以看到1秒过去了才func()返回。然而,没有存储 std::future std::async(...);- 即:auto f = std::async(...)
这似乎有效 - 但我想知道它的工作机制是什么。如果我有一个 std::future (在我的小例子中是 auto f ),那么当它超出范围时,它会整理线程 - 即等待 1 秒,然后线程在幕后被处理。
进一步测试:
start 18737230ms
stop 18738230ms
Run Code Online (Sandbox Code Playgroud)
给出:
start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed
Run Code Online (Sandbox Code Playgroud)
所以这表明存储未来意味着线程并行运行。不存储未来意味着线程似乎必须运行完成 - 我猜这是因为创建和销毁了临时未来?
std::async(...)所以我的结论是,如果你希望它并行运行(这就是重点),你不能只调用而不存储 std::future - 即使你不打算使用 future。
嗯...我想我刚刚说服了自己答案!- 但我不是 100% 确定我的推理是正确的 - 希望我有......
如果std::future是通过 创建的std::async,则析构函数将等待任务结束。这并不意味着任务不并行运行 - 它只是在变量范围末尾等待任务结束。std::async然而,它在不存储的情况下使用std::future有点棘手,我通常建议将 future 存储在某个地方以避免令人讨厌的意外。看一下有关析构函数的页面std::future(重点是我的):
这些操作不会阻止共享状态变为就绪状态,但如果满足以下所有条件,则可能会阻塞:共享状态是通过调用 std::async 创建的,共享状态尚未就绪,并且此是对共享状态的最后一个引用。