简体   繁体   English

NPTL将最大线程数限制为65528吗?

[英]NPTL caps maximum threads at 65528?

The following code is supposed to make 100,000 threads: 以下代码假定可以创建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);
}

This is running on a 64bit machine with 32GB of RAM; 它运行在具有32GB RAM的64位计算机上; Debian 5.0 installed, all stock. 已安装Debian 5.0,所有库存。

  • ulimit -s 512 to keep the stack size down ulimit -s 512来减小堆栈大小
  • /proc/sys/kernel/pid_max set to 1,000,000 (by default, it caps out at 32k pids). / proc / sys / kernel / pid_max设置为1,000,000(默认情况下,上限为32k pid)。
  • ulimit -u 1000000 to increase max processes (don't think this matters at all) ulimit -u 1000000增加最大进程数(根本不认为这很重要)
  • /proc/sys/kernel/threads-max set to 1,000,000 (by default, it wasn't set at all) / proc / sys / kernel / threads-max设置为1,000,000(默认情况下,完全没有设置)

Running this spits out the following: 运行此命令会吐出以下内容:

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

I'm certainly not running out of ram; 我当然不会用完内存。 I can even launch several more of these programs all running at the same time and they all start their 65k threads. 我什至可以启动多个同时运行的程序,它们都启动65k线程。

(Please refrain from suggesting I not try to launch 100,000+ threads. This is simple testing of something which should work. My current epoll-based server has roughly 200k+ connections at all times and various papers would suggest that threads just might be a better option. - Thanks :) ) (请不要建议我不要尝试启动100,000个以上的线程。这是对应该正常工作的简单测试。我当前的基于epoll的服务器始终具有大约200k +的连接, 各种论文都认为线程可能是一个更好的选择。 - 谢谢 :) )

pilcrow's mention of /proc/sys/vm/max_map_count is right on track; pilcrow对/proc/sys/vm/max_map_count是正确的; raising this value allows more threads to be opened; 增大该值将允许打开更多线程; not sure of the exact formula involved, but a 1mil+ value allows for some 300k+ threads. 不确定确切的公式,但是1mil +的值允许300k +线程。

(For anyone else experimenting with 100k+ threads, do look at pthread_create's mmap issues... making new threads gets really slow really fast when lower memory is used up.) (对于尝试使用100k +线程的其他用户,请查看pthread_create的mmap问题...当消耗较少的内存时,使新线程变得非常缓慢。)

One possible issue is the local variable thread in the main program. 一个可能的问题是主程序中的局部变量thread I think that pthread_t would be 8 bytes on your 64-bit machine (assuming 64-bit build). 我认为pthread_t在您的64位计算机上为8个字节(假定为64位版本)。 That would be 800,000 bytes on the stack. 那将是堆栈上的800,000字节。 Your stack limit of 512K would be a problem I think. 我认为您的512K堆栈限制是一个问题。 512K / 8 = 65536, which is suspiciously near the number of threads you are creating. 512K / 8 = 65536,这可疑地接近您正在创建的线程数。 You might try dynamically allocating that array instead of putting it on the stack. 您可以尝试动态分配该数组,而不是将其放在堆栈上。

This might help set the stack size in the program to the smallest it can go (if that's not enough you pick): 这可能有助于将程序中的堆栈大小设置为可以达到的最小大小(如果您选择的不够):

/* 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);
}

additionally you could add a call like this: pthread_attr_setguardsize(&thread_attr, 0); 另外,您可以添加如下调用: pthread_attr_setguardsize(&thread_attr, 0); just after the call to pthread_attr_setstacksize() but then you'd loose stack overrun detection entirely, and it'd only save you 4k of address space and zero actual memory. 在调用pthread_attr_setstacksize()但是您完全放弃了堆栈溢出检测,这只会为您节省4k的地址空间和零实际内存。

Are you trying to search for a formula to calculate max threads possible per process? 您是否要搜索公式来计算每个进程可能的最大线程数?

Linux implements max number of threads per process indirectly!! Linux间接实现了每个进程的最大线程数!

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

Thus, the number of threads per process can be increased by increasing total virtual memory or by decreasing stack size. 因此,可以通过增加总虚拟内存或通过减小堆栈大小来增加每个进程的线程数。 But, decreasing stack size too much can lead to code failure due to stack overflow while max virtual memory is equals to the swap memory. 但是,如果最大虚拟内存等于交换内存,则堆栈大小减小太多可能会由于堆栈溢出而导致代码失败。

Check you machine: 检查您的机器:

Total Virtual Memory: ulimit -v (default is unlimited, thus you need to increase swap memory to increase this) 虚拟内存总量: ulimit -v (默认为无限制,因此您需要增加交换内存来增加此数量)

Total Stack Size: ulimit -s (default is 8Mb) 总堆栈大小: ulimit -s (默认为8Mb)

Command to increase these values: 增加这些值的命令:

ulimit -s newvalue

ulimit -v newvalue

*Replace new value with the value you want to put as limit. *将新值替换为您要放入的值作为限​​制。

References: 参考文献:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM