Каково максимальное количество потоков, которые могут быть созданы процессом под Linux?
Как (если возможно) изменить это значение?
Каково максимальное количество потоков, которые могут быть созданы процессом под Linux?
Как (если возможно) изменить это значение?
В Linux нет отдельных потоков для каждого процесса, это всего лишь ограничение на общее количество процессов в системе (потоки по существу являются просто процессами с общим адресным пространством в Linux), которые вы можете просмотреть следующим образом:
cat /proc/sys/kernel/threads-max
По умолчанию используется количество страниц памяти /4. Вы можете увеличить это следующим образом:
echo 100000 > /proc/sys/kernel/threads-max
Также существует ограничение на количество процессов (и, следовательно, потоков), которые может создать один пользователь, см. ulimit/getrlimit
для получения подробных сведений об этих ограничениях.
Это НЕПРАВИЛЬНО сказать, что LINUX не имеет отдельных потоков для каждого процесса.
Linux реализует максимальное количество потоков в процессе косвенно!!
number of threads = total virtual memory / (stack size*1024*1024)
Таким образом, количество потоков на процесс может быть увеличено за счет увеличения общей виртуальной памяти или уменьшения размера стека. Но слишком большой размер стека может привести к сбою кода из-за, в то время как максимальная виртуальная память равна памяти подкачки.
Проверьте машину:
Общая виртуальная память: ulimit -v
(по умолчанию не ограничено, поэтому вам нужно увеличить память подкачки, чтобы увеличить ее)
Общий размер стека: ulimit -s
(по умолчанию 8 Мб)
Команда для увеличения этих значений:
ulimit -s newvalue
ulimit -v newvalue
* Замените новое значение на значение, которое вы хотите поставить как ограничение.
Литература:
http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/
В практическом плане предел обычно определяется пространством стека. Если каждый поток получает 1 МБ стек (я не могу вспомнить, является ли это по умолчанию в Linux), то у вас 32-разрядная система закончит адресное пространство после 3000 потоков (если предположить, что последний gb зарезервирован для ядра).
Однако вы, скорее всего, испытаете ужасную производительность, если используете более нескольких десятков потоков. Рано или поздно вы получаете слишком много перераспределения контекста, слишком много накладных расходов в планировщике и т.д. (Создание большого количества потоков делает немного больше, чем есть много памяти. Но много потоков с реальной работой, чтобы сделать, это замедлит вас, поскольку они борются за доступное время процессора)
Что вы делаете, когда это ограничение имеет значение?
правильные потоки 100k на linux:
ulimit -s 256
ulimit -i 120000
echo 120000 > /proc/sys/kernel/threads-max
echo 600000 > /proc/sys/vm/max_map_count
echo 200000 > /proc/sys/kernel/pid_max
./100k-pthread-create-app
2018 от @Thomas, на системных системах:
/etc/systemd/logind.conf: UserTasksMax=100000
@dragosrsupercool
Linux не использует виртуальную память для вычисления максимального потока, но физический оратор, установленный в системе
max_threads = totalram_pages / (8 * 8192 / 4096);
http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/
ядро /fork.c
/* The default maximum number of threads is set to a safe
* value: the thread structures can take up at most half
* of memory.
*/
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
Таким образом, поток max различается между каждой системой, потому что установленный ram может иметь разные размеры, я знаю, что Linux не нужно увеличивать виртуальную память, потому что на 32-битном мы получили 3 ГБ для пользовательского пространства и 1 ГБ для ядро, на 64-битном мы получили 128 ТБ виртуальной памяти, которые происходят на Solaris, если вы хотите увеличить виртуальную память, вам нужно добавить пространство подкачки.
Чтобы получить его:
cat /proc/sys/kernel/threads-max
Чтобы установить его:
echo 123456789 > /proc/sys/kernel/threads-max
123456789 = # потоков
Ограничение количества потоков:
$ cat /proc/sys/kernel/threads-max
Как он рассчитывается:
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
и: размер страницы x86_64 (PAGE_SIZE) - 4K; Как и во всех других архитектурах, x86_64 имеет стек ядра для каждого активного потока. Эти потоки потоков THREAD_SIZE (2 * PAGE_SIZE) большие;
для mempages:
cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';
так что фактически число не связано с ограничением размера стека памяти потока (ulimit -s
).
PS: ограничение стека памяти потока составляет 10 М в моей rhel VM, а для памяти 1,5 ГБ эта виртуальная машина может позволить себе только 150 потоков?
Возможно, это не имеет значения. Вы будете получать гораздо лучшую производительность при разработке своего алгоритма для использования фиксированного количества потоков (например, 4 или 8, если у вас 4 или 8 процессоров). Вы можете сделать это с рабочими очередями, асинхронным IO или чем-то вроде libevent.
Используйте nbio
неблокирующий ввод/вывод
библиотека или что-то еще, если вам нужно больше потоков для выполнения вызовов ввода/вывода, которые блокируют
проверьте размер стека на поток с помощью ulimit, в моем случае Redhat Linux 2.6:
ulimit -a
...
stack size (kbytes, -s) 10240
Каждый из ваших потоков получит этот объем памяти (10 МБ), назначенный для него. С 32-битной программой и максимальным адресным пространством 4 ГБ, это максимум 4096 МБ /10 МБ = 409 потоков! Минус-код программы, минус кучи пространства, вероятно, приведет к наблюдаемому максимуму. из 300 потоков.
Вы можете повысить это, выполнив компиляцию и запуск на 64-битной основе или установив ulimit -s 8192 или даже ulimit -s 4096. Но если это целесообразно, это еще одно обсуждение...
Зависит от вашей системы, просто напишите образец программы [путем создания процессов в цикле] и проверьте с помощью ps axo pid, ppid, rss, vsz, nlwp, cmd. Когда он больше не может создавать потоки, проверьте nlwp count [nlwp - это число потоков] voila, у вас есть ответ на ваш дурак, вместо того, чтобы идти через книги
Для тех, кто смотрит на это сейчас, на системные системы (в моем случае, в частности, Ubuntu 16.04) есть еще один предел, который применяется параметром pid.max группы.
По умолчанию установлено 12 288 и может быть переопределено в /etc/systemd/logind.conf
Другие советы по-прежнему применяются, включая pids_max, threads-max, max_maps_count, ulimits и т.д.
Мы можем видеть максимальное количество потоков, определенных в следующем файле в linux
cat/proc/sys/kernel/threads-max
(ИЛИ)
sysctl -a | grep threads-max
Чтобы установить навсегда,
vim /etc/sysctl.conf
и добавьте
kernel.threads-max = "value"
Вы можете увидеть текущее значение с помощью следующих command- cat/proc/sys/kernel/threads-max
Вы также можете установить значение, подобное
echo 100500>/proc/sys/kernel/threads-max
Установленное вами значение будет проверяться на доступных страницах ОЗУ. Если структуры потоков занимают более 1/8) доступных страниц ОЗУ, поток-max будет соответственно уменьшен.
Да, для увеличения номера потоков вам необходимо увеличить виртуальную память или уменьшить размер стека. В Raspberry Pi я не нашел способ увеличить виртуальную память, если уменьшить размер стека от 8 МБ до 1 МБ. Возможно, он получает более 1000 потоков на один процесс, но уменьшает размер стека с помощью команды "ulimit -s" это для всех потоков. Таким образом, моим решением было использование класса потоков pthread_t "thread", потому что pthread_t позволяет мне устанавливать размер стека для каждого потока. Наконец, я имею возможность архивировать более 1000 потоков в процессе в малине Pi, каждый из которых имеет 1 МБ стека.