Когда программа запускается в Linux, экземпляр этой программы загружается в память вместе со всеми необходимыми ресурсами. Этот экземпляр программы в памяти называется процессом. Процессы Linux — и, более конкретно, процессы с большим весом (HWP) — включают в себя много накладных расходов при их создании или при переключении на них из другого процесса. Но поток – это облегченный процесс (LWP) в компьютерной операционной системе, который может совместно использовать ресурсы, такие как код, данные, файловый ввод-вывод, таблицы стеков и сигналов. Это то, что делает их легкими. В отличие от процессов, потокам не нужно очищать и воссоздавать все таблицы заново, прежде чем их можно будет переключать. Следовательно, их можно переключать проще и чаще.
Однако Linux не проводит различия между процессом и потоком на уровне операционной системы. Потоки по-прежнему являются процессами в Linux, только потоки могут совместно использовать определенные ресурсы с другими процессами. В отличие от других операционных систем, Linux не предоставляет никаких специфичных для потоков структур данных или параметров планирования. Ядро не делает здесь различий.
Но потоки или облегченные процессы все еще можно использовать в Linux для достижения параллелизма и многоядерной обработки путем разделения процесса на несколько потоков. Таким образом, каждый поток может выполняться на отдельном процессорном ядре для достижения истинного параллелизма. Поскольку легковесные процессы в Linux уже настолько легковесны, переключение между потоками не требует больших накладных расходов.
В этой статье будут рассмотрены ограничения потоков и процессов в системе Linux, способы определения этих ограничений, способы увеличения максимального количества потоков и, наконец, несколько распространенных команд для проверки количества потоков на процесс в системе Linux.
Как и в любой операционной системе, в Linux существуют определенные ограничения на количество потоков. Linux хранит конфигурации в виде файлов, и большинство параметров конфигурации ядра хранятся в пути /proc/sys/kernel/. Конфигурация для максимального количества потоков, которые может выполнять ядро, хранится в proc/sys/kernel/threads-max. Использование команды cat в этом файле отобразит максимальное количество потоков для системы. Например, ниже указано максимальное количество потоков равно 3935. Это было запущено на одноядерном сервере, используемом для размещения статического веб-сайта, поэтому максимальное количество потоков невелико по сравнению с многоядерными процессорами:
[rootelocalhost ~]# cat /proc/sys/kernel/threads-max 3935 [root@localhost ~]#
Команда sysctl также может использоваться с параметром и может быть отфильтрована с помощью grep для проверки той же конфигурации ядра. Ниже показан вывод команды ниже:
sysctl -a | grep threads-max
[rootelocalhost -]# cat /proc/sys/kernel/threads-max 3935 [root@localhost ~]# sysctl -a | grep threads-max kernel.threads-max =3935 [root@localhost ~]#
Вы можете видеть выше, что обе команды выдают одинаковый результат. Аналогично, существует параметр конфигурации ядра для максимального количества процессов, которые ядро может выполнять одновременно. Эта конфигурация присутствует в файле по адресу /proc/sys/kernel/pid_max. Мы можем просмотреть этот файл, чтобы увидеть количество, как показано ниже:
[rootelocalhost -]#cat /proc/sys/kernel/pid_max 32768 [rootelocalhost ~]#
Выходные данные получены с того же одноядерного сервера, поэтому их количество невелико. Это число также соответствует точке, вокруг которой обтекаются идентификаторы процессов или PID, поэтому мы можем периодически сталкиваться с дублированием PID во время обслуживания.
Поскольку Linux не делает различий между процессами и потоками, максимальное количество процессов также является максимальным количеством потоков. Если система достигнет предела и ни один из процессов не будет готов к завершению, система не сможет создавать никаких новых процессов и, соответственно, не сможет создавать никаких новых потоков.
Количество потоков в Linux ограничено несколькими факторами, в первую очередь размером виртуальной памяти. Формула, используемая для расчета максимального количества потоков в системе, равна:
максимальное количество потоков = размер виртуальной памяти / (размер стека * 1024 * 1024)
Как показывает формула, увеличение размера виртуальной памяти или уменьшение размера стека на поток приведет к увеличению максимального количества потоков. Чтобы более точно выполнить эту настройку, для проверки текущего размера стека в системе можно использовать команду ulimit:
ulimit -a | grep "stack size"
Ниже показан размер стека одноядерного сервера:
[root@localhost ~]# ulimit -a | grep "stack size" -s: stack size (kb) 8192 [root@localhost ~]#
Мы можем изменить этот размер стека, используя ту же команду ulimit:
ulimit -s 8192
Linux предоставляет несколько команд для простого перечисления всех процессов и потоков, а также для фильтрации потоков для данного процесса. В следующем разделе показано, как использовать эти команды для получения информации, связанной с потоками.
Команда ps вместе с ее параметрами используется для составления списка всех процессов, запущенных в системе Linux, и полезной информации о них. Однако без каких-либо параметров команда выдает только снимок текущих процессов, как показано на рисунке 1 ниже:
При использовании опции e также отображаются все имена процессов. На скриншоте на рисунке 2 показана часть выходных данных этой команды:
Чтобы получить больше данных в синтаксисе BSD, параметры aux можно использовать следующим образом:
ps aux
Эта команда предоставит такую информацию, как процент процессора и памяти, используемых процессом, команда, используемая для запуска этого процесса, и как долго процесс выполняется.
Информация, относящаяся к каждому процессу, хранится в отдельном файле в каталоге /proc. Используя идентификатор процесса, вы можете прочитать в файле состояния количество потоков, созданных этим конкретным процессом.
На рисунке 3 ниже процесс с PID 42 создал 1 поток. Команда для получения количества потоков процесса:
cat /proc/<pid>/status
Файл состояния предоставляет гораздо больше информации о процессе, чем просто количество потоков. Чтобы определить количество потоков для процесса, есть еще один метод, который использует тот же каталог /proc.
Точно так же, как у каждого процесса есть каталог, созданный под его PID, у каждого потока есть каталог, созданный под его идентификатором потока. Это находится в каталоге /proc/<pid>/task. Общее количество каталогов в каталоге задач – это количество потоков, созданных для процесса.
Этого можно добиться, передав выходные данные команды ls в команду wc для подсчета количества каталогов, как показано ниже:
ls /proc/<pid>/task | wc -l
Далее показан вывод команды для того же процесса, показанного ниже:
[rootelocalhost -]# ls /proc/42/task | wc -1 [rootelocalhost ~]#
Команда ps помогает получить информацию о потоках процесса. Благодаря возможности отображать информацию только для данного PID, получить количество для отдельного процесса становится проще.
Возможны следующие варианты:
Как и раньше, выходные данные этой команды затем передаются в команду wc для подсчета количества строк и получения количества потоков. Полная команда выглядит следующим образом:
ps hH p <PID> | wc -l
Все три метода последовательно дают одинаковые результаты.
Потоки используются для ускорения выполнения процессов за счет увеличения параллелизма, поскольку каждый поток может выполняться на ядре процессора. Потоки также можно использовать, чтобы убедиться, что процесс не блокирует другие процессы или потоки, пока он ожидает завершения ввода-вывода файла или другой операции.
Но, как и в случае с процессами, существуют ограничения на количество процессов или потоков, которые могут выполняться одновременно в системе Linux. Это число можно увеличить, изменив конфигурацию нескольких параметров ядра.
Поскольку Linux делает небольшое различие между потоками и процессами, все ограничения, которые применяются к процессам, применяются и к потокам. Используя эти простые команды, упомянутые выше, администраторы Linux могут проверить количество потоков для данного процесса.