在我关注的教程中,作者编写了一个程序,该程序显示 std::future
的析构函数并不总是执行任务。在下面的程序中,使用 std::async()
创建的 10 个线程被移入 vector 中,然后我们等待它们的析构函数运行。
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
int main()
{
std::cout << "Main thread id: " << std::this_thread::get_id() << std::endl;
std::vector<std::future<void>> 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
的生命即将结束,推迟它们有什么意义?
最佳答案
the author wrote a program that showed that the destructors of std::futures don't always execute the task.
析构函数从不执行任务。如果任务已经在另一个线程中执行,析构函数会等待它完成,但不会执行它。
what we found was that only 6 threads were launched when the destructors ran
这是不正确的,线程在析构函数运行时没有启动,它们在您调用 std::async
时启动(或之后的某个时间),并且在析构函数启动时它们仍在运行,所以析构函数必须等待它们。
What is the point of deferring them if the life of the std::future is ending?
同样,当析构函数运行时,它们不会延迟,当 std::async
被调用时,它们会延迟,当析构函数运行时,它们仍然会延迟,因此它们只是被丢弃而没有被调用运行,析构函数不必等待任何事情。
我不知道您是在引用教程而作者感到困惑,还是您感到困惑,但您对所发生情况的描述具有误导性。
每次您在没有启动策略参数的情况下调用 std::async
时,C++ 运行时都会决定是创建一个新线程还是推迟该函数(以便它可以稍后运行)。如果系统很忙,运行时可能会决定推迟该函数,因为启动另一个线程会使系统变得更慢。
关于c++ - 为什么有些线程会延迟?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27301667/