【问题标题】:C++, Clang, system_error: thread constructor failed: Resource temporarily unavailableC++,Clang,system_error:线程构造函数失败:资源暂时不可用
【发布时间】:2014-01-22 17:00:50
【问题描述】:
#include <atomic>
#include <thread>
#include <iostream>
#include <vector>

std::atomic<int> i (0);


void add_one()
{
    std::this_thread::sleep_for(std::chrono::seconds(1)); // [1]
    ++i;                                                  // [2]
}


int main()
{
    std::vector<std::thread> threads;
    while(i < 10)
    {
        threads.push_back(std::thread(&add_one));
    }                                                    // [3]
    std::cout << "num threads: " << threads.size() << std::endl;
    for(auto& t : threads)
    {
        t.detach();
    }

    std::cout << "i: " << i << std::endl;

    return 0;   
}

这段代码有很多错误,我什至不知道如何开始。最初我只是想说服自己原子 int 真的是原子的。所以我开始构建一些代码来做到这一点。在 OSX 上运行时(使用 Clang 编译),当前代码将给出“system_error:线程构造函数失败:资源暂时不可用”。使用 Visual Studio 在 Windows 上没有错误。这是由 [1] 行引起的。如果我将 [1] 移到 [2] 之后,则不会出错。

但让我大吃一惊的是,这 [3] 应该是一个无限循环!我不知道线程在构造时会开始执行它被赋予的函数。我一直认为那是thread.join 或thread.detach。有没有办法构造一个线程对象并告诉它在我希望它启动之前不要做任何事情?

有鉴于此,线程构造函数在运行时发出警告,因为它等待的时间太长,这并不让我感到惊讶,但是当我将第 [1] 行移到 [2 之后,为什么它会消失]? 什么时候搬?

void add_one()
{
    ++i;
    std::this_thread::sleep_for(std::chrono::seconds(5));
    std::cout << "blah" << std::endl;
}

Blah 永远不会显示,即使是乱码、非线程安全的方式也是如此。就像它从未存在过一样。

在 windows 上会打印这些废话。

对于我所面临的巨大困惑,我深表歉意。

【问题讨论】:

    标签: c++ multithreading c++11 clang


    【解决方案1】:

    您的程序正在快速创建线程并在达到某个上限(我的系统上的 2048 个线程)时终止。切换行时它不会失败,因为现在子线程会立即递增 i,这会导致 for 循环在一切崩溃之前终止。

    你不能在 C++11 中创建挂起线程(我不知道为什么。也许他们想要支持不支持这种能力的操作系统)。正确的解决方法是在执行其他任何操作之前让线程在某些情况下阻塞。不过,为了学习目的,像你一样睡一秒钟就可以了。

    【讨论】:

      【解决方案2】:

      但是为什么当我将第 [1] 行移到 [2] 之后时它会消失?

      简单。在第 2 行之前使用第 1 行,您可以让线程在递增i 之前等待一秒钟。启动一个线程可能很昂贵,但它不会花费任何时间接近一秒钟。您正在创建大量线程,所有线程都在等待一秒钟到期。当计时器到期时,它们都会自动递增i。在那之前,您的程序正在迅速创建越来越多的线程。在这些计时器中的任何一个到期之前,您的程序就会用完资源。

      当您在第 [2] 行之后移动第 [1] 行时,您的主循环会创建递增 i 然后休眠的线程。睡眠的唯一影响是延迟对detach 的调用。您仍然会创建十多个线程,但不会更多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多