在我关注的教程中,作者编写了一个程序,该程序显示std::future
s 的析构函数并不总是执行任务.在下面的程序中,创建的10个线程std::async()
被移动到向量中,然后我们等待它们的析构函数运行.
#include
#include
#include
#include
int main()
{
std::cout << "Main thread id: " << std::this_thread::get_id() << std::endl;
std::vector> futures;
for (int i = 0; i < 10; ++i)
{
auto fut = std::async([i]
{
std::this_thread::sleep_for(std::chrono::seconds(2));
std::cout << std::this_thread::get_id() << " ";
});
futures.push_back(std::move(fut));
}
}
结果取决于机器,但我们发现在析构函数运行时只启动了6个线程(我们在主线程id输出后只打印了6个ID).这意味着其他四个被延迟,并且延迟线程在std::future
析构函数期间不会运行.
我的问题是为什么有些线程被迫执行而其他线程被推迟.如果生命std::future
结束,那么推迟他们的意义何在?
作者写了一个程序,表明std :: futures的析构函数并不总是执行任务.
析构函数永远不会执行任务.如果任务已在另一个线程中执行,则析构函数会等待它完成,但它不会执行它.
我们发现在析构函数运行时只启动了6个线程
这是不正确的,线程在析构函数运行时不会启动,它们在您调用时std::async
(或之后的某个时间)启动,并且它们在析构函数启动时仍在运行,因此析构函数必须等待它们.
如果std :: future的生命结束,那么推迟他们的意义何在?
同样,它们在析构函数运行时不会延迟,它们在std::async
调用时会延迟,它们在析构函数运行时仍然会延迟,因此它们只是在没有运行的情况下被抛弃,并且析构函数不必等待任何事情.
我不知道你是否引用了这个教程,而且作者对此感到困惑,或者如果你感到困惑,但你对所发生的事情的描述会产生误导.
每次调用时都std::async
没有启动策略参数,C++运行时决定是创建新线程还是推迟该函数(因此可以稍后运行).如果系统繁忙,运行时可能会决定推迟该功能,因为启动另一个线程会使系统更慢.