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

发布于 2024-09-15 01:46:41 字数 1946 浏览 1 评论 0原文

以下代码应该创建 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);
}

该代码在具有 32GB RAM 的 64 位计算机上运行;已安装 Debian 5.0,全部现货。

  • ulimit -s 512 保持堆栈大小较小
  • /proc/sys/kernel/pid_max 设置为 1,000,000 (默认情况下,上限为 32k pid)。
  • 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+ 连接,各种论文表明线程可能是一个更好的选择。 - 谢谢 :) )

The following code is supposed to make 100,000 threads:

/* 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; Debian 5.0 installed, all stock.

  • ulimit -s 512 to keep the stack size down
  • /proc/sys/kernel/pid_max set to 1,000,000 (by default, it caps out at 32k pids).
  • ulimit -u 1000000 to increase max processes (don't think this matters at all)
  • /proc/sys/kernel/threads-max set to 1,000,000 (by default, it wasn't set at all)

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.

(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 :) )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

青芜 2024-09-22 01:46:41

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

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

pilcrow's mention of /proc/sys/vm/max_map_count is right on track; 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.

(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.)

神爱温柔 2024-09-22 01:46:41

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

One possible issue is the local variable thread in the main program. I think that pthread_t would be 8 bytes on your 64-bit machine (assuming 64-bit build). That would be 800,000 bytes on the stack. Your stack limit of 512K would be a problem I think. 512K / 8 = 65536, which is suspiciously near the number of threads you are creating. You might try dynamically allocating that array instead of putting it on the stack.

揽月 2024-09-22 01:46:41

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

/* 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 的地址空间和零实际内存。

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); 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.

谢绝鈎搭 2024-09-22 01:46:41

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

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/

Are you trying to search for a formula to calculate max threads possible per process?

Linux implements max number of threads per process indirectly!!

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)

Total Stack Size: ulimit -s (default is 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/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文