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

これは、32 GB の 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 ベースのサーバーには常に約 20 万以上の接続があり、さまざまな論文では、スレッドの方が優れた選択肢である可能性があることが示唆されています。 。 - ありがとう :) )

4

4 に答える 4

6

ピルクロウの言及は/proc/sys/vm/max_map_count順調です。この値を上げると、より多くのスレッドを開くことができます。関連する正確な式はわかりませんが、1mil+ の値で 300k+ のスレッドが可能です。

(100,000 以上のスレッドを試している人は、pthread_create の mmap の問題を確認してください。新しいスレッドの作成は、メモリが少なくなると非常に速くなります。)

于 2010-08-19T16:37:58.260 に答える
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

thread考えられる問題の 1 つは、メイン プログラムのローカル変数です。pthread_t は、64 ビット マシンでは 8 バイトになると思います (64 ビット ビルドを想定)。これは、スタック上で 800,000 バイトになります。512K のスタック制限が問題になると思います。512K / 8 = 65536、これは作成しているスレッドの数に疑わしいほど近いです。その配列をスタックに置くのではなく、動的に割り当ててみてください。

于 2010-08-19T14:00:30.220 に答える
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 に答える