以下两个陈述在执行方面有何区别?
async([]() { ... });
thread([]() { ... }).detach();
答案 0 :(得分:15)
std::async ([]() { ... }); // (1)
std::thread ([]() { ... }).detach (); // (2)
大多数情况下,在讨论std::async
时,首先注意到它已被破坏,这个名称意味着当返回值不被承认时不能保留的东西(分配给要在其中被破坏的变量)当前范围的结束)。
在这种情况下,std::async
的断裂正是导致(1)
和(2)
之间巨大差异的原因。 一个会阻止,另一个则不会。
为什么std::async
会在此上下文中屏蔽?
std::async
的返回值是std::future
,它有一个阻塞析构函数,必须在代码继续之前执行。
在一个示例中,因为下面的g
在f
完成之前不会执行,只是因为(3)
的未使用的返回值在完成所有工作之前无法销毁相关声明。
std::async (f); // (3)
std::async (g); // (4)
std::thread (...).detach ()
的目的是什么?
从std::thread
分离时,我们只是说; “我不再关心这个线程句柄,请执行该死的东西。”
继续使用与前一个类似的示例(约std::async
),差异非常明显; f
和g
都会同时执行。
std::thread (f).detach ();
std::thread (g).detach ();
答案 1 :(得分:2)
async
会返回future
个对象,detach
则不会。所有detach
都允许执行独立继续。为了达到与async
类似的效果,您必须使用join
。例如:
{
std::async(std::launch::async, []{ f(); });
std::async(std::launch::async, []{ g(); }); // does not run until f() completes
}
{
thread1.join();
thread2.join();
}
答案 2 :(得分:1)
我知道您的问题给出了很好的答案,但是如果我们要更改您的问题,将会发生一些有趣的事情。
想象一下,您保留了async
返回的未来,并且没有分离线程,而是为此创建了一个变量,
异步代码
auto fut=std::async([]() { ... });
std::thread th([]() { ... });
现在您已经设置了这两种构造不同的原因。
th.join()//you're here until the thread function returns
fut.wait_for(std::chrono::seconds(1)); //wait for 1 sec then continue.
在加入thread
时,async
是一个全有或全无的东西,您可以在其中检查 int numOfDots = 0;
//While not ready after waiting 1 sec do some stuff and then check again
while(fut.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
{
(numOfDots++)%=20;
//Print status to the user you're still working on it.
std::cout << "Working on it" <<std::string(numOfDots,'.')<<"\r"<<std::flush();
}
std::cout << "Thanks for waiting!\nHere's your answer: " << fut.get() <<std::endl();
并进行其他操作。
wait_for
实际上会返回一个状态,因此您可以执行以下操作。
{{1}}