運行這個程式時線程限制.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 的堆疊(這可能非常危險),您仍然需要 1.2GB 的堆疊才能擁有 600 個執行緒。無論您的工作是什麼,線程都不是適合它的工具。
答案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無關。