При запуске этой программыthread-limit.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
чтобы узнать размер стека потока по умолчанию для вашей платформы. Обратите внимание, что если поток превысит выделенный ему стек, ваш процесс умрет.
Даже при стеке в 2 МБ, что может быть очень опасно, вы все еще смотрите на 1,2 ГБ только для стеков, чтобы иметь 600 потоков. Какой бы ни была ваша работа, потоки — неподходящий инструмент для нее.
решение2
Это не имеет ничего общего с ограничениями потоков. Код ошибки 12 не относится к ограничениям потоков.
$ perror 12
OS error code 12: Cannot allocate memory
Полагаю, если у вас заканчивается стек, то если вы установите его на значение по умолчанию RedHat в 8 МБ, то, вероятно, сможете запустить больше потоков.
Это то же самое, что и связанное с явными размерами стека, установленными на 8 МБ. Посмотрите, что произойдет, когда вы скомпилируете это.
/* 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.