c++ - 为什么有些线程会延迟?

标签 c++ multithreading c++11

在我关注的教程中,作者编写了一个程序,该程序显示 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/

相关文章:

c++ - 这个线程池/多核模拟有什么问题

c++ - Autoconf 被 C++11 库拒绝,被编译器接受,被预处理器拒绝

c++ - std::vector::erase 异常安全

c++ - 派生带/不带参数的基类函数

c++ - 如何从头开始启动 MFC 应用程序?

c# - 同时等待多个任务中的一个任务

c++ - 使用 Variadic 模板的任意维数组

c++ - std::istringstream::peek() 是否应该设置 eof 标志?

C++ CppUnit 测试 (CPPUNIT_ASSERT)

asp.net-mvc - 如果许多线程同时访问数据库的同一表,linqtosql是否会注意?