このプログラムを実行するとスレッド制限.c私の専用 Debian サーバーでは、出力には、システムが約 600 以上のスレッドを作成できないと表示されます。より多くのスレッドを作成し、システムの誤った構成を修正する必要があります。
専用サーバーに関する情報をいくつか紹介します。
de801:/# uname -a
Linux de801.ispfr.net 2.6.18-028stab085.5 #1 SMP Thu Apr 14 15:06:33 MSD 2011 x86_64 GNU/Linux
de801:/# java -version
java version "1.6.0_26"
Java(TM) SE Runtime Environment (build 1.6.0_26-b03)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02, mixed mode)
de801:/# ldd $(which java)
linux-vdso.so.1 => (0x00007fffbc3fd000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00002af013225000)
libjli.so => /usr/lib/jvm/java-6-sun-1.6.0.26/jre/bin/../lib/amd64/jli/libjli.so (0x00002af013441000)
libdl.so.2 => /lib/libdl.so.2 (0x00002af01354b000)
libc.so.6 => /lib/libc.so.6 (0x00002af013750000)
/lib64/ld-linux-x86-64.so.2 (0x00002af013008000)
de801:/# cat /proc/sys/kernel/threads-max
1589248
de801:/# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 794624
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 10240
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 128
cpu time (seconds, -t) unlimited
max user processes (-u) unlimited
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Cプログラムの出力は次のようになります
de801:/test# ./thread-limit
Creating threads ...
Address of c = 1061520 KB
Address of c = 1081300 KB
Address of c = 1080904 KB
Address of c = 1081168 KB
Address of c = 1080508 KB
Address of c = 1080640 KB
Address of c = 1081432 KB
Address of c = 1081036 KB
Address of c = 1080772 KB
100 threads so far ...
200 threads so far ...
300 threads so far ...
400 threads so far ...
500 threads so far ...
600 threads so far ...
Failed with return code 12 creating thread 637.
これを修正する方法について何かアイデアはありますか?
答え1
一度に 600 を超えるスレッドを作成する必要はありません。同時に実行できる便利な処理に対してのみスレッドが必要です。システムは一度に 600 を超える処理を便利に実行することはできません。より多くの作業を実行するために、より多くのスレッドは必要ありません。
いずれにせよ、スタック サイズの設定が間違っています。コードによって作成されていない初期スレッド スタックの制限サイズを設定しています。コードによって作成されるスレッドのスタックのサイズを設定する必要があります。
変化:
printf("Creating threads ...\n");
for (i = 0; i < MAX_THREADS && rc == 0; i++) {
rc = pthread_create(&(thread[i]), NULL, (void *) &run, NULL);
(大まかに)
printf("Creating threads ...\n");
pthread_attr_t pa;
pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa, 2*1024*1024);
for (i = 0; i < MAX_THREADS && rc == 0; i++) {
rc = pthread_create(&(thread[i]), &pa, (void *) &run, NULL);
phtread_attr_destroy(&pa);
pthread_attr_getstacksize
また、プラットフォームのデフォルトのスレッド スタック サイズを確認するために呼び出すこともできます。スレッドが割り当てられたスタックを超えると、プロセスが終了することに注意してください。
2MB のスタックでも、非常に危険ですが、600 スレッドのスタックだけで 1.2GB が必要になります。どのような作業であっても、スレッドは適切なツールではありません。
答え2
これはスレッド制限とは関係ありません。エラー コード 12 はスレッド制限には適用されません。
$ perror 12
OS error code 12: Cannot allocate memory
スタックが不足している場合は、RedHat のデフォルトの 8MB に設定すれば、より多くのスレッドを実行できる可能性があります。
これは、明示的なスタック サイズが 8MB に設定されたリンクされたものと同じです。これをコンパイルすると何が起こるかを確認してください。
/* compile with: gcc -lpthread -o thread-limit thread-limit.c */
/* originally from: http://www.volano.com/linuxnotes.html */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#define MAX_THREADS 10000
int i;
void run(void) {
char c;
if (i < 10)
printf("Address of c = %u KB\n", (unsigned int) &c / 1024);
sleep(60 * 60);
}
int main(int argc, char *argv[]) {
struct rlimit limits;
limits.rlim_cur = 1024*1024*8;
limits.rlim_max = 1024*1024*8;
if (setrlimit(RLIMIT_STACK, &limits) == -1) {
perror("Failed to set stack limit");
exit(1);
}
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.\n",
rc, i + 1);
}
exit(0);
}
答え3
次の情報を受け取りました: これはホスト プロバイダーによって課せられた制限です。これはプログラミングや Linux とは何の関係もありません。