NPTL最大线程为65528?

时间:2010-08-19 11:55:13

标签: c linux multithreading pthreads nptl

以下代码应该生成100,000个线程:

/* compile with:   gcc -lpthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

#define MAX_THREADS 100000
int i;

void run(void) {
  sleep(60 * 60);
}

int main(int argc, char *argv[]) {
  int rc = 0;
  pthread_t thread[MAX_THREADS];
  printf("Creating threads ...\n");
  for (i = 0; i < MAX_THREADS && rc == 0; i++) {
    rc = pthread_create(&(thread[i]), NULL, (void *) &run, NULL);
    if (rc == 0) {
      pthread_detach(thread[i]);
      if ((i + 1) % 100 == 0)
    printf("%i threads so far ...\n", i + 1);
    }
    else
    {
      printf("Failed with return code %i creating thread %i (%s).\n",
         rc, i + 1, strerror(rc));

      // can we allocate memory?
      char *block = NULL;
      block = malloc(65545);
      if(block == NULL)
        printf("Malloc failed too :( \n");
      else
        printf("Malloc worked, hmmm\n");
    }
  }
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use
  exit(0);
}

这是在64位机器上运行,内存为32GB;安装了Debian 5.0,所有库存。

  • ulimit -s 512以保持堆栈大小下降
  • / proc / sys / kernel / pid_max设置为1,000,000(默认情况下,它的上限为32k pids)。
  • ulimit -u 1000000增加最大进程(不要认为这很重要)
  • / proc / sys / kernel / threads-max设置为1,000,000(默认情况下,根本没有设置)

运行此程序会吐出以下内容:

65500 threads so far ...
Failed with return code 12 creating thread 65529 (Cannot allocate memory).
Malloc worked, hmmm

我当然没有用完公羊;我甚至可以在同一时间启动这些程序中的几个并且它们都启动它们的65k线程。

(请不要建议我不要尝试启动100,000多个线程。这是对应该工作的东西的简单测试。我当前基于epoll的服务器始终有大约200k +连接{{{ 3}}会建议线程可能是更好的选择。 - 谢谢:))

4 个答案:

答案 0 :(得分:6)

pilcrow提到/proc/sys/vm/max_map_count正在走上正轨;提高此值可以打开更多线程;不确定所涉及的确切公式,但1mil +值允许大约300k +线程。

(对于尝试使用100k +线程的其他人,请查看pthread_create's mmap个问题...当较低的内存用完时,新线程会变得非常慢。)

答案 1 :(得分:0)

一个可能的问题是主程序中的局部变量thread。我认为pthread_t在你的64位机器上是8个字节(假设64位构建)。这将是堆栈上的800,000字节。我认为你的堆栈限制为512K是个问题。 512K / 8 = 65536,这可疑地接近您正在创建的线程数。您可以尝试动态分配该数组,而不是将其放在堆栈中。

答案 2 :(得分:0)

这可能有助于将程序中的堆栈大小设置为它可以达到的最小值(如果这还不够你选择):

/* compile with:   gcc -lpthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>

#define MAX_THREADS 100000
int i;

void run(void) {
  sleep(60 * 60);
}

int main(int argc, char *argv[]) {
  int rc = 0;
  pthread_t thread[MAX_THREADS];
  pthread_attr_t thread_attr;

  pthread_attr_init(&thread_attr);
  pthread_attr_setstacksize(&thread_attr, PTHREAD_STACK_MIN);

  printf("Creating threads ...\n");
  for (i = 0; i < MAX_THREADS && rc == 0; i++) {
    rc = pthread_create(&(thread[i]), &thread_attr, (void *) &run, NULL);
    if (rc == 0) {
      pthread_detach(thread[i]);
      if ((i + 1) % 100 == 0)
    printf("%i threads so far ...\n", i + 1);
    }
    else
    {
      printf("Failed with return code %i creating thread %i (%s).\n",
         rc, i + 1, strerror(rc));

      // can we allocate memory?
      char *block = NULL;
      block = malloc(65545);
      if(block == NULL)
        printf("Malloc failed too :( \n");
      else
        printf("Malloc worked, hmmm\n");
    }
  }
sleep(60*60); // ctrl+c to exit; makes it easier to see mem use
  exit(0);
}

另外你可以在调用pthread_attr_setguardsize(&thread_attr, 0);之后添加这样的调用:pthread_attr_setstacksize()但是你完全松开了堆栈溢出检测,它只能为你节省4k的地址空间零实际记忆。

答案 3 :(得分:0)

您是否正在尝试搜索公式以计算每个流程可能的最大线程数?

  

Linux间接实现每个进程的最大线程数!!

number of threads = total virtual memory / (stack size*1024*1024)

因此,可以通过增加总虚拟内存或减少堆栈大小来增加每个进程的线程数。但是,过多地减少堆栈大小会导致代码失败,因为堆栈溢出,而最大虚拟内存等于交换内存。

检查你的机器:

虚拟内存总量:ulimit -v(默认为无限制,因此您需要增加交换内存以增加此值)

总堆栈大小:ulimit -s(默认为8Mb)

增加这些值的命令:

ulimit -s newvalue

ulimit -v newvalue

*将新值替换为您想要设置为限制的值。

<强>参考文献:

http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/