pthread_create可以创建的最大线程数是多少?

inj*_*joy 10 c linux pthreads

可能重复:
pthread_create创建的线程与内核线程相同?

我使用下面的代码来测试pthread_create函数可以创建的最大线程数.

#include <pthread.h>
#include <stdio.h>

static unsigned long long thread_nr = 0;

pthread_mutex_t mutex_;

void* inc_thread_nr(void* arg) {
    (void*)arg;
    pthread_mutex_lock(&mutex_);
    thread_nr ++;
    pthread_mutex_unlock(&mutex_);

    /* printf("thread_nr = %d\n", thread_nr); */

    sleep(300000);
}

int main(int argc, char *argv[])
{
    int err;
    int cnt = 0;

    pthread_t pid[1000000];

    pthread_mutex_init(&mutex_, NULL);

    while (cnt < 1000000) {

        err = pthread_create(&pid[cnt], NULL, (void*)inc_thread_nr, NULL);
        if (err != 0) {
            break;
        }
        cnt++;
    }

    pthread_join(pid[cnt], NULL);

    pthread_mutex_destroy(&mutex_);
    printf("Maximum number of threads per process is = %d\n", thread_nr);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

Maximum number of threads per process is = 825
Run Code Online (Sandbox Code Playgroud)

这是pthread_create函数可以创建的最大线程数吗?

此外,我使用以下命令查看我的系统允许的最大线程数:

# cat /proc/sys/kernel/threads-max
Run Code Online (Sandbox Code Playgroud)

而这个数字是772432.

为什么我的程序输出不等于threads-max

我的操作系统是Fodaro 16,有12个内核,48G内存.

Nom*_*mal 8

每个线程堆栈的默认大小是人为地在测试中强加限制.虽然给予进程的默认堆栈(初始线程)会根据需要动态增长,但其他线程的堆栈大小是固定的.默认大小通常非常大,类似于2兆字节,以确保每个线程堆栈足够大,甚至可以用于病理情况(深度递归等).

在大多数情况下,线程工作者只需要很少的堆栈.我发现在我使用的所有体系结构中,每个线程堆栈64k(65536字节)就足够了,只要我不使用深度递归算法或大型局部变量(结构或数组).

要显式指定每线程堆栈大小,请将您修改main()为以下内容:

#define MAXTHREADS 1000000
#define THREADSTACK  65536

int main(int argc, char *argv[])
{
    pthread_t       pid[MAXTHREADS];
    pthread_attr_t  attrs;
    int  err, i;
    int  cnt = 0;

    pthread_attr_init(&attrs);
    pthread_attr_setstacksize(&attrs, THREADSTACK);

    pthread_mutex_init(&mutex_, NULL);

    for (cnt = 0; cnt < MAXTHREADS; cnt++) {

        err = pthread_create(&pid[cnt], &attrs, (void*)inc_thread_nr, NULL);
        if (err != 0)
            break;
    }

    pthread_attr_destroy(&attrs);

    for (i = 0; i < cnt; i++)
        pthread_join(pid[i], NULL);

    pthread_mutex_destroy(&mutex_);

    printf("Maximum number of threads per process is %d (%d)\n", cnt, thread_nr);
}
Run Code Online (Sandbox Code Playgroud)

请注意,呼叫attrs不会消耗此信息pthread_create().想想线程属性更像是模板pthread_create()应该如何创建线程; 它们不是赋予线程的属性.这让许多有抱负的pthreads程序员兴奋不已,所以这是你最好从一开始就做到的事情之一.

至于堆栈大小本身,它必须至少PTHREAD_STACK_MIN(在Linux中为16384,我相信)并且可以被整除sysconf(_SC_PAGESIZE).由于页面大小在所有体系结构上都是2的幂,因此使用足够大的2的幂应始终有效.

另外,我也在那里添加了修复程序.您只尝试加入一个不存在的线程(循环尝试创建但未通过的线程),但您需要加入所有这些线程(以确保它们都完成了它们的工作).

进一步推荐的修复:

而不是使用睡眠,使用条件变量.pthread_cond_wait()让条件变量上的每个线程等待()(同时按住互斥锁),然后释放互斥锁并退出.这样你的main函数只需要pthread_cond_broadcast()在条件变量上广播()来告诉它们现在可以退出的所有线程,然后它就可以连接每个线程,并且你可以确定那个线程数实际上是并发运行的.正如您的代码现在所说,某些线程可能有足够的时间从睡眠状态唤醒并退出.

  • 请注意,“&lt;limits.h&gt;”应定义“PTHREAD_STACK_MIN”,这是架构线程函数所需的最小堆栈大小。因此,您可以使用例如“#define THREADSTACK (PTHREAD_STACK_MIN + 32768)”,但为了可移植性,您应该将其四舍五入为“sysconf(_SC_PAGESIZE)”的倍数。 (2认同)

P.P*_*.P. 6

理论上,一个进程可以拥有的线程数量没有限制。但实际限制可能来自所有线程共享资源的事实。

这意味着在某些时候,由于缺乏与此类堆栈空间共享的资源,进程无法创建超过一定数量的进程。

  • 很可能由于堆栈过多而导致内存不足。在 32 位机器上,默认堆栈大小为 2M,因此如果有 825 个线程,则需要超过 1.5 GB 的内存。64 位系统使用 8M 堆栈,因此超过 6.5 GB。 (2认同)