考虑以下代码:
#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;
}
outputs:
start 18737230ms
stop 18738230ms
我们可以看到1秒过去了func()
返回。但是没有存储 std::futurestd::async(...);
- IE。: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() << "ms\n";
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() << "ms\n";
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() << "ms\n";
return 0;
}
gives:
start 4448133ms
stop1 4449133ms - 1 sec passed
stop2 4449133ms - almost no time passed
所以这表明存储未来意味着线程并行运行。不存储未来意味着线程似乎必须运行完成 - 我猜这是因为创建和销毁了临时未来?
所以我的结论是你不能只打电话std::async(...)
如果您希望它并行运行(这就是重点),则无需存储 std::future - 即使您不打算使用 future。
嗯...我想我刚刚说服了自己答案! - 但我不是 100% 确定我的推理是正确的 - 希望我有......