#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;
}
这段代码错误太多,我什至不知道如何开始。最初我只是想说服自己原子整数真的是原子的。所以我着手构建一些代码来做到这一点。当在 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 上将打印 blahs。
对于我面临的巨大困惑,我深表歉意。
最佳答案
您的程序正在快速创建线程并在达到某个上限(我的系统上为 2048 个线程)时终止。当您切换行时它不会失败,因为现在子线程立即递增 i,这会导致 for 循环在一切崩溃之前终止。
你不能在 C++11 中创建挂起线程(我不知道为什么。也许他们想支持不支持这种能力的操作系统)。正确的解决方法是在执行任何其他操作之前让线程在某些情况下阻塞。不过,出于学习目的,像您一样睡一秒钟就可以了。
关于C++, clang ,系统错误 : thread constructor failed: Resource temporarily unavailable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20930518/