运行该程序时线程限制.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 无关。