Каково максимальное количество потоков, которые может создать pthread? [дубликат]
Возможные Дубликаты:
поток, созданный pthread_create то же самое с потоком ядра?
я использую приведенный ниже код для проверки максимального количества потоков, которые может создать функция pthread_create.
#include <pthread.h>
#include <stdio.h>
static unsigned long long thread_nr = 0;
pthread_mutex_t mutex_;
void* inc_thread_nr(void* arg) {
(void*)arg;
pthread_mutex_lock(&mutex_);
thread_nr ++;
pthread_mutex_unlock(&mutex_);
/* printf("thread_nr = %dn", thread_nr); */
sleep(300000);
}
int main(int argc, char *argv[])
{
int err;
int cnt = 0;
pthread_t pid[1000000];
pthread_mutex_init(&mutex_, NULL);
while (cnt < 1000000) {
err = pthread_create(&pid[cnt], NULL, (void*)inc_thread_nr, NULL);
if (err != 0) {
break;
}
cnt++;
}
pthread_join(pid[cnt], NULL);
pthread_mutex_destroy(&mutex_);
printf("Maximum number of threads per process is = %dn", thread_nr);
}
и выход:
Maximum number of threads per process is = 825
это максимальное количество потоков, которое может создать функция pthread_create?
кроме того, я использую команду ниже для просмотра максимального количества потоков моя система позволяет:
# cat /proc/sys/kernel/threads-max
и номер 772432.
почему выход моей программы не равно значению threads-max
?
моя ОС-Fodaro 16, С 12 ядрами, 48G ОЗУ.
3 ответов
размер по умолчанию для стека на поток искусственно накладывает ограничение в вашем тесте. В то время как стек по умолчанию для процесса (исходный поток) растет динамически, по мере необходимости, стеки для других потоков фиксированного размера. Размер по умолчанию обычно очень большой, что-то вроде двух мегабайт, чтобы убедиться, что стек на поток достаточно велик даже для патологических случаев (глубокая рекурсия и так далее).
в большинстве случаев, работникам потока нужно очень маленький стек. Я обнаружил, что на всех архитектурах, которые я использовал, достаточно 64K (65536 байт) на стек потока, если я не использую глубоко рекурсивные алгоритмы или большие локальные переменные (структуры или массивы).
чтобы явно указать размер стека для каждого потока, измените свой main()
Для что-то вроде следующего:
#define MAXTHREADS 1000000
#define THREADSTACK 65536
int main(int argc, char *argv[])
{
pthread_t pid[MAXTHREADS];
pthread_attr_t attrs;
int err, i;
int cnt = 0;
pthread_attr_init(&attrs);
pthread_attr_setstacksize(&attrs, THREADSTACK);
pthread_mutex_init(&mutex_, NULL);
for (cnt = 0; cnt < MAXTHREADS; cnt++) {
err = pthread_create(&pid[cnt], &attrs, (void*)inc_thread_nr, NULL);
if (err != 0)
break;
}
pthread_attr_destroy(&attrs);
for (i = 0; i < cnt; i++)
pthread_join(pid[i], NULL);
pthread_mutex_destroy(&mutex_);
printf("Maximum number of threads per process is %d (%d)\n", cnt, thread_nr);
}
отметим, что attrs
не потребляется pthread_create()
звонок. Подумайте о атрибутах потока больше как о шаблоне how pthread_create()
создать нити; они не являются атрибутами данного потока. Это срабатывает много начинающих программистов pthreads, так что это одна из тех вещей, которые вам лучше получить прямо с самого начала.
Что касается самого размера стека, он должен быть по крайней мере PTHREAD_STACK_MIN
(16384 в Linux, я считаю) и делится на sysconf(_SC_PAGESIZE)
. Поскольку размер страницы-это сила двух на всех архитектурах, использование достаточно большой силы двух всегда должно работать.
кроме того, я добавил исправление в ней есть. Вы только попробуйте присоединиться к несуществующему потоку (тот, который цикл пытался создать, но не удалось), но вам нужно присоединиться ко всем из них (чтобы убедиться, что они все сделали свою работу).
дополнительные рекомендуемые исправления:
вместо использования сна используйте переменную условия. Пусть каждый поток ждет (pthread_cond_wait()
) в переменной условия (удерживая мьютекс), затем отпустите мьютекс и выйдите. Таким образом, ваша основная функция должна только транслировать (pthread_cond_broadcast()
) на переменной условия, чтобы сказать все потоки теперь они могут выйти, затем он может присоединиться к каждому из них, и вы можете быть уверены, что это количество потоков действительно работает одновременно. Поскольку ваш код стоит сейчас, у некоторых потоков может быть достаточно времени, чтобы проснуться от сна и выйти.
теоретически, нет ограничений на количество потоков, которые может иметь процесс. Но практическое ограничение может исходить из того, что все потоки разделяют ресурсы.
Это означает, что в какой-то момент процесс не может создать больше определенного количества процессов из-за отсутствия ресурсов для совместного использования с таким пространством стека, например.
по данным pthread_create(3)
man page, есть еще один предел:
RLIMIT_NPROC soft resource limit (set via setrlimit(2)), which limits the number
of process for a real user ID.
попробуйте найти значение этого предела с помощью getrlimit(2)
. Если значение по-прежнему не соответствует измеренному вами числу (825), попробуйте изменить это ограничение на setrlimit(2)
чтобы проверить, влияет ли это на ваши измерения.
EDIT: на самом деле предельное значение RLIMIT_NPROC такое же, как и полученное с помощью команды оболочки ulimit -u
(который печатает / устанавливает максимальные пользовательские процессы).