5

以下代码应该产生 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

我当然不会用完 ram。我什至可以同时启动更多这些程序,它们都启动了它们的 65k 线程。

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

4

4 回答 4

6

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

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

于 2010-08-19T16:37:58.260 回答
0

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

于 2010-08-19T14:00:30.220 回答
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 的地址空间和零实际内存。

于 2010-11-22T19:46:53.430 回答
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/

于 2012-02-09T14:06:18.567 回答