Максимальное количество потоков на процесс в Linux?
Какое максимальное количество потоков может быть создано процессом в Linux?
Как (если возможно) это значение может быть изменено?
18 ответов
В 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
(по умолчанию 8Mb)
Команда для увеличения этих значений:
ulimit -s newvalue
ulimit -v newvalue
* Замените новое значение значением, которое вы хотите установить в качестве предела.
Рекомендации:
http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/
С практической точки зрения, предел обычно определяется пространством стека. Если каждый поток получает 1 МБ стека (я не помню, если это по умолчанию в Linux), то у вас 32-разрядная система исчерпает адресное пространство после 3000 потоков (при условии, что последний ГБ зарезервирован для ядра),
Однако вы, скорее всего, будете испытывать ужасную производительность, если будете использовать более нескольких десятков потоков. Рано или поздно вы получаете слишком много накладных расходов на переключение контекста, слишком много накладных расходов в планировщике и так далее. (Создание большого количества потоков делает немного больше, чем просто потребляет много памяти. Но большое количество потоков с реальной работой замедлит вас, поскольку они борются за доступное время процессора)
Что вы делаете, когда этот предел даже актуален?
Правильные темы 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 для систем systemd:
/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);
Таким образом, максимальный поток в каждой системе различен, потому что установленный 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) составляет 4 КБ; Как и все другие архитектуры, x86_64 имеет стек ядра для каждого активного потока. Эти стеки потоков имеют размер THREAD_SIZE (2*PAGE_SIZE);
для бугорков:
cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';
так что на самом деле число не связано с ограничением размера стека памяти потока (ulimit -s
).
PS: ограничение стека памяти в моей виртуальной виртуальной машине составляет 10 МБ, а для 1,5 ГБ памяти эта виртуальная машина может позволить себе только 150 потоков?
Для тех, кто смотрит на это сейчас, в системах systemd (в моем случае, в частности, в Ubuntu 16.04) есть еще одно ограничение, устанавливаемое параметром cgroup pids.max.
По умолчанию это значение равно 12 288, и его можно переопределить в /etc/systemd/logind.conf.
Другие рекомендации по-прежнему применимы, включая pids_max, threads-max, max_maps_count, ulimits и т. Д.
Проверьте размер стека на поток с помощью 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. Но если это целесообразно, другое обсуждение...
Это, вероятно, не должно иметь значения. Вы достигнете гораздо большей производительности, если будете разрабатывать алгоритм с использованием фиксированного числа потоков (например, 4 или 8, если у вас 4 или 8 процессоров). Вы можете сделать это с рабочими очередями, асинхронным вводом-выводом или чем-то вроде libevent.
Использование nbio
неблокирующая библиотека ввода-вывода или что-то еще, если вам нужно больше потоков для выполнения вызовов ввода-вывода, которые блокируют
Зависит от вашей системы, просто напишите пример программы [путем создания процессов в цикле] и проверьте, используя ps axo pid,ppid,rss,vsz,nlwp,cmd. Когда он больше не может создавать потоки, проверьте количество nlwp [ nlwp - это число потоков] вуаля, вы получили свой надежный ответ вместо того, чтобы идти по книгам
Чтобы установить постоянно,
vim /etc/sysctl.conf
и добавить
kernel.threads-max = "value"
Я думаю, мы пропустили еще одно ограничение, которое также заблокирует создание нового потока, это ограничение kernel.pid_max .
root@myhost:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.7 LTS
Release: 16.04
Codename: xenial
root@myhost:~# uname -a
Linux myhost 4.4.0-190-generic #220-Ubuntu SMP Fri Aug 28 23:02:15 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Я обнаружил, что, по крайней мере, в моей системе этот порог kernel.pid_max равен 32768. Когда я запускаю любой простой процесс JVM, он сообщает об ошибке, как показано ниже:
java/jstack/jstat ...
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
# An error report file with more information is saved as:
# /root/hs_err_pid1390.log
Проверь память, достаточно.
root@lascorehadoop-15a32:~# free -mh
total used free shared buff/cache available
Mem: 125G 11G 41G 1.2G 72G 111G
Swap: 0B 0B 0B
Проверьте системный поток:
~# ps -eLf|wc -l
31506
Но я проверяю системный лимит по ulimit:
root@myhost:~# 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) 515471
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 98000
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 515471
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
Из вывода ulimit мы могли видеть, что в настоящее время количество потоков намного меньше максимального лимита пользовательского процесса.
Фактически, достигнутый предел - это
kernel.pid_max
Его очень легко проверить и настроить: https://www.cyberciti.biz/tips/howto-linux-increase-pid-limits.html
Мы можем увидеть максимальное количество потоков, определенных в следующем файле в Linux
cat / proc / sys / kernel / threads-max
(ИЛИ ЖЕ)
sysctl -a | grep threads-max
Вы можете увидеть текущее значение с помощью следующей команды: cat /proc/sys/kernel/threads-max
Вы также можете установить значение как
echo 100500 > /proc/sys/kernel/threads-max
Установленное вами значение будет проверено по доступным страницам ОЗУ. Если структуры потоков занимают более 1/8-й) доступных страниц ОЗУ, поток-макс будет соответственно уменьшен.
Если вы используете Suse, вам нужно использовать один из этих методов
https://www.suse.com/support/kb/doc/?id=000015901
Глобальный,
/etc/systemd/system.conf
DefaultTasksMax=Value
Для конкретной службы ssh
/etc/systemd/system/sshd.service.d/override.conf
TasksMax=Value
Да, чтобы увеличить количество потоков, вам нужно увеличить виртуальную память или уменьшить размер стека. В Raspberry Pi я не нашел способа увеличить виртуальную память, если уменьшить размер стека со значения по умолчанию 8 МБ до 1 МБ. Возможно, получится более 1000 потоков на процесс, но уменьшится размер стека с помощью команды "ulimit -s". сделать это для всех потоков. Итак, мое решение было использовать экземпляр "pthread_t" "класс потока", потому что pthread_t позволяет мне устанавливать размер стека для каждого потока. Наконец, я могу архивировать более 1000 потоков на процесс в Raspberry Pi, каждый из которых имеет 1 МБ стека.