在循环中创建线程时出现C ++错误 [英] C++ Error when creating threads in loops

查看:94
本文介绍了在循环中创建线程时出现C ++错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Visual Studio 2015中运行以下命令时遇到问题.

I have a problem when running the following in Visual studio 2015.

#include <thread>
#include <vector>
#include <iostream>
using namespace std;

int main() {

    for (int i = 0; i < 10000; i++) {
        cout << "Loop: " << i << endl;

        vector<thread> threads;
        for (int j = 0; j < 8; j++) {
            try {
                threads.push_back(thread([]() {int a = 4; a++; }));
            }
            catch (const system_error &se) {
                cout << se.what() << endl;
                exit(1);
            }
        }

        for (int j = 0; j < 8; j++) {
            threads.at(j).join();
        }
    }

    return 0;
}

运行了数千次循环后,程序会在输出中捕获到system_error:

After a few thousand loops have been run the program catches a system_error with the output:

...
3994
3995
3996
3997
3998
resource unavailable try again: resource unavailable try again

我知道最大数量的线程可以同时运行,但是在这种情况下,只有8个线程同时运行,之后它们被销毁.可以创建的总数最大吗?

I know that there is a maximum number of threads that can be run simultaneously but in this case there's only 8 being run simultaneously after which they're destroyed. Is there a maximum on the total number that can be created?

我曾尝试在Linux上使用g ++来运行上述程序,并且仅在出现错误的Windows(Visual Studio和mingw)上运行良好.有什么帮助吗? 谢谢.

I have tried running the above on Linux with g++ and it runs fine its only on windows (both visual studio and mingw) that the error occurs. Any help? Thanks.

推荐答案

最好通过了解如何在Windows上创建线程来描述发生的事情.

What happened here is best described by understanding how threads are created on windows.

每个线程在创建时都会被赋予默认1Mb堆栈大小.您会注意到大约有3998个线程,大约相当于3.9Gb的已用用户地址空间.这并非偶然,因为这对应于64位窗口(内核空间为64位)下可用于32位进程的全部4Gb用户地址空间的大部分.多余的空间是可执行文件和必要的系统DLL被加载到的地方.

Each thread when it's created is given a default 1Mb stack size. You'll notice you're getting to approximately 3998 threads which would correspond to approximately 3.9Gb of used user address space. This is not an accident, as this corresponds to most of the full 4Gb user address space available to a 32bit process under 64bit windows (Kernel space is 64bit). The extra space is where the executable and necessary system DLLs are getting loaded into.

通过将内部版本更改为64位,可以大大扩展该地址空间.具有10000个具有1Mb堆栈的线程是一个水桶,而

By changing the build to 64bit you've massively expanded that address space. Having 10000 threads with a 1Mb stack is a drop in a bucket and the limiter becomes non-pagable kernel memory although the 1Mb stacks can and will be paged out causing the system to slow to a crawl.

这篇关于在循环中创建线程时出现C ++错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆