Linux максимальное количество потоков

Обновлено: 07.07.2024

Каково максимальное количество потоков, которые могут быть созданы процессом под Linux?

Как (если возможно) изменить это значение?

В Linux нет отдельных потоков для каждого процесса, это всего лишь ограничение на общее количество процессов в системе (потоки по существу являются просто процессами с общим адресным пространством в Linux), которые вы можете просмотреть следующим образом:

По умолчанию используется количество страниц памяти /4. Вы можете увеличить это следующим образом:

Также существует ограничение на количество процессов (и, следовательно, потоков), которые может создать один пользователь, см. ulimit/getrlimit для получения подробных сведений об этих ограничениях.

Ограничение в / proc / sys / vm / max_map_count также может ограничивать количество потоков. Должно быть безопасно увеличить этот лимит, если вы его достигнете. Роберт: Linux реализует ограничение на процесс косвенно. Проверьте мой ответ для деталей;) Я пытаюсь изменить это на моем Ubuntu 12.04, и это не меняется с вашей командой. Я также попытался vi, чтобы изменить его, но я получаю E667: Fsync failed когда я пытаюсь сохранить на vi. @dragosrsupercool максимальный поток рассчитывается с использованием общего оперативной памяти, без виртуальной памяти Размер стека на поток (по умолчанию в вашей системе), скорее всего, будет пределом, чем что-либо еще. Уменьшение размера стека для каждого потока - это способ увеличить общее количество потоков (хотя это редко хорошая идея).

Это НЕПРАВИЛЬНО сказать, что LINUX не имеет отдельных потоков для каждого процесса.

Linux реализует максимальное количество потоков в процессе косвенно!!

Таким образом, количество потоков на процесс может быть увеличено за счет увеличения общей виртуальной памяти или уменьшения размера стека. Но слишком большой размер стека может привести к сбою кода из-за, в то время как максимальная виртуальная память равна памяти подкачки.

Проверьте машину:

Общая виртуальная память: ulimit -v (по умолчанию не ограничено, поэтому вам нужно увеличить память подкачки, чтобы увеличить ее)

Общий размер стека: ulimit -s (по умолчанию 8 Мб)

Команда для увеличения этих значений:

* Замените новое значение на значение, которое вы хотите поставить как ограничение.

Литература:

За исключением 3 маленьких деталей: 1. Linux не делает этого, наличие стеков и тот факт, что память и адресное пространство имеют конечный размер, не имеют к этому никакого отношения. 2. Вы должны указать стек потока при его создании, это независимо от ulimit -s . Очень возможно (не разумно, но возможно) создать столько потоков, сколько существует возможных идентификаторов потоков. В 64-битном Linux даже легко «возможно» создать больше потоков, чем имеется идентификаторов потоков (конечно, это невозможно, но в отношении стека это так). 3. Резерв стека, коммит и виртуальная машина - это разные вещи, особенно с OC. Да, чтобы увеличить количество потоков, вам нужно увеличить виртуальную память или уменьшить размер стека. В Raspberry Pi я не нашел способа увеличить виртуальную память, если уменьшить размер стека со значения по умолчанию 8 МБ до 1 МБ. Возможно получить более 1000 потоков на процесс, но уменьшить размер стека с помощью команды «ulimit -s» сделать это для всех потоков. Итак, мое решение было использовать экземпляр «pthread_t» «класс потока», потому что pthread_t позволил мне установить размер стека для каждого потока. Наконец, я могу архивировать более 1000 потоков на процесс в Raspberry Pi каждый с 1 МБ стека

В практическом плане предел обычно определяется пространством стека. Если каждый поток получает 1 МБ стек (я не могу вспомнить, является ли это по умолчанию в Linux), то у вас 32-разрядная система закончит адресное пространство после 3000 потоков (если предположить, что последний gb зарезервирован для ядра).

Однако вы, скорее всего, испытаете ужасную производительность, если используете более нескольких десятков потоков. Рано или поздно вы получаете слишком много перераспределения контекста, слишком много накладных расходов в планировщике и т.д. (Создание большого количества потоков делает немного больше, чем есть много памяти. Но много потоков с реальной работой, чтобы сделать, это замедлит вас, поскольку они борются за доступное время процессора)

Какое максимальное количество потоков может быть создано процессом в Linux?

Как (если возможно) можно изменить это значение?

Ответ 1

В Linux нет отдельного ограничения потоков для каждого процесса, только ограничение на общее количество процессов в системе (потоки — это, по сути, просто процессы с общим адресным пространством в Linux), которые вы можете просмотреть следующим образом:

cat /proc/sys/kernel/threads-max

По умолчанию это количество страниц памяти/4. Это значение можно увеличить так:

echo 100000 > /proc/sys/kernel/threads-max

Также существует ограничение на количество процессов (и, следовательно, потоков), которые может создать один пользователь.

Ответ 2

НЕПРАВИЛЬНО утверждать, что в LINUX нет отдельных потоков для каждого процесса.

Linux косвенно реализует максимальное количество потоков на процесс .

number of threads = total virtual memory / (stack size*1024*1024)

Таким образом, количество потоков на процесс можно увеличить, увеличив общую виртуальную память или уменьшив размер стека. Но слишком большое уменьшение размера стека может привести к сбою кода из-за переполнения стека, в то время как максимальная виртуальная память равна размеру памяти подкачки.

Общая виртуальная память: ulimit -v (по умолчанию не ограничено, поэтому вам нужно увеличить память подкачки, чтобы увеличить это значение) .

Общий размер стека: ulimit -s (по умолчанию 8 М б ) .

Команда для увеличения этих значений:

ulimit -s newvalue

ulimit -v newvalue

* Замените новое значение значением, которое вы хотите установить в качестве ограничения.

Ответ 3

На практике предел обычно определяется размером стека. Если каждый поток получает стек размером 1 М б , тогда у вас в 32-разрядной системе адресное пространство закончится после 3000 потоков (при условии, что последний Г б зарезервирован для ядра).

Рано или поздно вы получите слишком много накладных расходов на переключение контекста, слишком много накладных расходов в планировщике и т. д. (Создание большого количества потоков создает много накладных расходов. Но множество потоков с реальной работой тормозит производительность, поскольку они борются за доступное время процессора) .

Ответ 4

Linux не использует виртуальную память для вычисления максимального количества потоков, а только физическую память, установленную в системе.

max_threads = totalram_pages / (8 * 8192 / 4096);

ядро/fork.c

/* Максимальное количество потоков по умолчанию установлено в безопасное значение.

* значение структуры потоков могут занимать не более половины памяти.

*/

max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);

Таким образом, максимальный поток различается для каждой системы, потому что установленная оперативная память может быть разного размера, поэтому Linux не нужно увеличивать виртуальную память, потому что на 32-битной версии у нас есть 3 Г б для пользовательского пространства и 1 Г б — для ядра, на 64-битной версии мы получили 128 Т б виртуальной памяти, что и происходит в Solaris. Если вы хотите увеличить виртуальную память, вам нужно добавить объем подкачки.

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.


Приглашаем всех желающих посетить открытый демо-урок «Практикум по написанию Ansible роли». На этом вебинаре участники вместе с экспертом будут писать, тестировать и отлаживать ansible роли. Это важно для тех, кто хочет автоматизировать настройку инфраструктуры, поскольку это один из инструментов, который это позволяет сделать. Сетевой стек — одна из самых запутанных вещей в Linux. И не только из-за сложности некоторых концепций и терминов, но и из-за изменения смысла некоторых параметров в разных версиях ядра. В этой статье приведена информация для ядра 2.2 и выше, а также, там где это возможно, указано различие между версиями вплоть до 5.5.

Очередь приема и netdev_max_backlog

Очередь ожидающих запросов на соединение и tcp_max_syn_backlog

Соединения создаются для SYN-пакетов из очереди приема и перемещаются в очередь ожидания (SYN Backlog Queue). Также соединение помечается как "SYN_RECV" и клиенту отправляется "SYN+ACK". Эти соединения не перемещаются в очередь установленных соединений ожидающих обработки accept() (accept queue) до тех пор, пока не будет получен и обработан соответствующий ACK. Максимальное количество соединений в этой очереди устанавливается параметром net.ipv4.tcp_max_syn_backlog .

Для просмотра очереди приема используйте команду netstat . На правильно настроенном сервере при нормальной нагрузке значение не должно быть больше 1. При большой нагрузке значение должно быть меньше размера очереди ожидания (SYN Backlog):

Если в состоянии "SYN_RECV" находятся много соединений, то можно также подстроить продолжительность нахождения SYN-пакета в этой очереди.

SYN Cookie

Повторы SYN+ACK

Что происходит, если SYN+ACK отправлен, но ответа ACK нет? В этом случае сетевой стек сервера повторит отправку SYN+ACK. Задержка между попытками вычисляется таким образом, чтобы обеспечить восстановление сервера. Если сервер получает SYN и отправляет SYN+ACK, но не получает ACK, то тайм-аут повторной передачи вычисляется по экспоненте (Exponental Backoff) и, следовательно, зависит от количества повторных попыток. Количество повторных попыток отправки SYN+ACK задается параметром ядра net.ipv4.tcp_synack_retries (по умолчанию равно 5). Повторные попытки будут через следующие интервалы: 1с, 3с, 7с, 15с, 31с. При шести попытках последняя будет примерно через 63 секунды после первой. Это позволяет удержать SYN-пакет в очереди ожидания более 60 секунд до истечения времени ожидания пакета. Если очередь SYN backlog мала, то не требуется большого количества соединений, чтобы возникла ситуация, когда полуоткрытые соединения никогда не завершатся и тогда никакие соединения не смогут быть установлены. Установите количество повторных попыток SYN+ACK равным 0 или 1, чтобы избежать такого поведения на высоконагруженных серверах.

Повторы SYN

Несмотря на то что повторные SYN-пакеты отправляются клиентом во время ожидания SYN+ACK, они могут влиять и на высоконагруженные серверы, работающие с прокси-соединениями. Например, сервер nginx, устанавливающий несколько десятков прокси-соединений к бэкенд-серверу, из-за всплесков трафика может на некоторое время перегрузить сетевой стек, а повторные попытки создадут дополнительную нагрузку на бэкэнд как в очереди приема, так и в очереди ожидания (SYN backlog). Это, в свою очередь, может повлиять на клиентские соединения. Повторные попытки SYN контролируются параметром net.ipv4.tcp_syn_retries (по умолчанию 5 или 6 в зависимости от дистрибутива). Ограничьте количество повторных попыток SYN до 0 или 1, чтобы не было долгих повторных попыток отправки в течение 63–130 с.

Более подробно о проблемах с клиентскими соединениями при обратном прокси-сервере читайте в статье Linux Kernel Tuning for High Performance Networking: Ephemeral Ports.

Очередь установленных соединений ожидающих принятия (accept queue) и somaxconn

Очередь запросов на соединение создает приложение, используя listen() и указывая размер очереди в параметре "backlog". Начиная с ядра 2.2 поведение этого параметра изменилось с максимального количества неоконченных запросов на соединение, которое может удерживать сокет, на максимальное количество полностью установленных соединений, ожидающих, пока они будут приняты. Как описано выше, максимальное количество неоконченных запросов на соединение теперь задается с помощью параметра ядра net.ipv4.tcp_max_syn_backlog .

somaxconn и параметр backlog в listen()

Хотя за размер очереди для каждого слушателя отвечает приложение, есть ограничение на количество соединений, которые могут находиться в очереди. Размером очереди управляют два параметра: 1) параметр backlog в функции listen() и 2) параметр ядра net.core.somaxconn , задающий максимальный размер очереди.

Значения по умолчанию для очереди

Значение по умолчанию для net.core.somaxconn берется из константы SOMAXCONN, которая в ядрах Linux вплоть до версии 5.3 имеет значение 128, но в 5.4 она была увеличена до 4096. Однако, на момент написания этой статьи, ядро 5.4 еще не очень распространено, поэтому в большинстве систем значение будет 128, если вы не модифицировали net.core.somaxconn.

Часто приложения для размера очереди по умолчанию используют константу SOMAXCONN, если этот размер не задается в конфигурации приложения. Хотя некоторые приложения устанавливают и свои значения по умолчанию. Например, в nginx размер очереди равен 511, который автоматически усекается до 128 в ядрах Linux до версии 5.3.

Изменение размера очереди

Многие приложения позволяют указывать размер очереди в конфигурации, указывая значение параметра backlog для listen() . Если приложение вызывает listen() со значением backlog , превышающим net.core.somaxconn, то размер очереди будет автоматически усечен до значения SOMAXCONN.

Потоки

Соединения и файловые дескрипторы

Системные ограничения

Любое сокетное соединение использует файловый дескриптор. Максимальное количество дескрипторов, которые могут быть созданы в системе, задается параметром ядра fs.file-max. Посмотреть количество используемых дескрипторов можно следующим образом:

Пользовательские ограничения

Помимо системного ограничения количества файловых дескрипторов, у каждого пользователя есть свои лимиты. Они настраиваются в системном файле limits.conf (nofile) или, при запуске процесса под управлением systemd, в unit-файле systemd (LimitNOFILE). Чтобы увидеть значение по умолчанию запустите:

Для systemd (на примере nginx):

Настройка

Для настройки системных ограничений установите параметр ядра fs.max-file в максимальное количество файловых дескрипторов, которое может быть в системе (с учетом некоторого буфера). Например:

Для настройки пользовательского лимита установите достаточно большое значение, чтобы хватило сокетам и файловым дескрипторам рабочих процессов (также с некоторым буфером). Пользовательские ограничения устанавливаются в /etc/security/limits.conf, в conf-файле в /etc/security/limits.d/ или в unit-файле systemd. Например:

Количество worker'ов

Аналогично файловым дескрипторам, количество worker'ов или потоков, которые может создать процесс, ограничено как на уровне ядра, так и на уровне пользователя.

Системные ограничения

Процессы могут создавать рабочие потоки. Максимальное количество потоков, которые могут быть созданы, задается параметром ядра kernel.threads-max . Для просмотра максимального и текущего количества потоков, выполняющихся в системе, запустите следующее:

Пользовательские ограничения

Есть свои ограничения и у каждого пользовательского процесса. Это также настраивается с помощью файла limits.conf (nproc) или unit-файла systemd (LimitNPROC). Для просмотра максимального количества потоков, которое может создать пользователь запустите:

Для systemd (на примере nginx):

Настройка

Как и в случае с nofile , ограничения для пользователей ( nproc ) устанавливаются в /etc/security/limits.conf, в conf-файле в /etc/security/limits.d/ или в unit-файле systemd. Пример с nproc и nofile :

Обратный прокси и TIME_WAIT

При большом всплеске трафика прокси-соединения, застрявшие в "TIME_WAIT", суммарно могут потреблять много ресурсов при закрытии соединения. Это состояние говорит, что клиент получил последний FIN-пакет от сервера (или вышестоящего worker'а) и находится в ожидании для корректной обработки пакетов. Время нахождения соединения в состоянии "TIME_WAIT" по умолчанию составляет 2 x MSL (Maximum Segment Length — максимальная длина сегмента), что составляет 2 x 60 с. В большинстве случаев это нормальное и ожидаемое поведение, и значение по умолчанию в 120 с вполне приемлемо. Однако много соединений в состоянии "TIME_WAIT" может привести к тому, что приложение исчерпает эфемерные порты для соединений к клиентскому сокету. В этом случае следует уменьшить FIN тайм-аут.

Управляет этим тайм-аутом параметр net.ipv4.tcp_fin_timeout . Рекомендуемое значение для высоконагруженных систем составляет от 5 до 7 секунд.

Собираем все вместе

Очередь приема (receive queue) должна быть рассчитана на обработку всех пакетов, полученных через сетевой интерфейс, не вызывая отбрасывания пакетов. Также необходимо учесть небольшой буфер на случай, если всплески будут немного выше, чем ожидалось. Для определения правильного значения следует отслеживать файл softnet_stat на предмет отброшенных пакетов. Эмпирическое правило — использовать значение tcp_max_syn_backlog, чтобы разрешить как минимум столько же SYN-пакетов, сколько может быть обработано для создания полуоткрытых соединений. Помните, что этот параметр задает количество пакетов, которое каждый процессор может иметь в своем буфере, поэтому разделите значение на количество процессоров.

Размер SYN очереди ожидания (SYN backlog queue) на высоконагруженном сервере должен быть рассчитан на большое количество полуоткрытых соединений для обработки редких всплесков трафика. Здесь эмпирическое правило заключается в том, чтобы установить это значение, по крайней мере, на максимальное количество установленных соединений, которое слушатель может иметь в очереди приема, но не выше, чем удвоенное количество установленных соединений. Также рекомендуется отключить SYN cookie, чтобы избежать потери данных при больших всплесках соединений от легитимных клиентов.

Очередь установленных соединений, ожидающих принятия (accept queue) должна быть рассчитана таким образом, чтобы в периоды сильного всплеска трафика ее можно было использовать в качестве временного буфера для установленных соединений. Эмпирическое правило — устанавливать это значение в пределах 20–25% от числа рабочих потоков.

Параметры

В этой статье были рассмотрены следующие параметры ядра:

И следующие пользовательские ограничения:

Заключение

Все параметры в этой статье приведены в качестве примеров и не должны вслепую применяться на ваших продакшн-серверах без тестирования. Есть и другие параметры ядра, которые влияют на производительность сетевого стека. Но в целом, это наиболее важные параметры, которые я использовал при настройке ядра для высоконагруженных систем.

какое максимальное количество потоков может быть создано процессом под Linux?

как (если возможно) это значение может быть изменено?

Linux не имеет отдельных потоков на ограничение процесса, просто ограничение на общее количество процессов в системе (потоки-это, по сути, просто процессы с общим адресным пространством в Linux), которые вы можете просмотреть следующим образом:

по умолчанию используется количество страниц памяти/4. Вы можете увеличить это как:

существует также ограничение на количество процессов (и, следовательно, потоков), которые может создать один пользователь, см. ulimit/getrlimit для получения подробной информации о эти рамки.

неверно говорить, что LINUX не имеет отдельных потоков на ограничение процесса.

Linux реализует максимальное количество потоков на процесс косвенно!!

таким образом, количество потоков на процесс может быть увеличено за счет увеличения общей виртуальной памяти или уменьшения размера стека. Но слишком большое уменьшение размера стека может привести к сбою кода из-за переполнения стека, в то время как максимальная виртуальная память равна swap память.

проверьте машину:

Общая Виртуальная Память: ulimit -v (по умолчанию не ограничено, поэтому вам нужно увеличить память подкачки увеличить это)

Общий Размер Стека: ulimit -s (по умолчанию 8 МБ)

*замените новое значение значением, которое вы хотите поместить как предел.

ссылки:

на практике предел обычно определяется пространством стека. Если каждый поток получает стек 1 МБ (я не могу вспомнить, является ли это значением по умолчанию в Linux), то у 32-разрядной системы закончится адресное пространство после 3000 потоков (при условии, что последний ГБ зарезервирован для ядра).

однако вы, скорее всего, испытаете ужасную производительность, если будете использовать более нескольких десятков потоков. Рано или поздно вы получаете слишком много накладных расходов на переключение контекста, слишком много накладных расходов в планировщик и так далее. (Создание большого количества потоков делает немного больше, чем съедает много памяти. Но много потоков с actual работа делать будет замедлять вас, как они борются за доступное время процессора)

Что вы делаете, когда этот предел будет еще актуальна?

правильные потоки 100k в linux:

2018 обновление от @Thomas, на системах systemd:

Linux не использует виртуальную память для вычисления максимума потока, но физический ОЗУ, установленный в системе

таким образом, поток max отличается между каждой системой, потому что установленный ОЗУ может быть разных размеров, я знаю, что Linux не нужно увеличивать виртуальная память, потому что на 32 бит мы получили 3 ГБ для пользовательского пространства и 1 ГБ для ядра, на 64 бит мы получили 128 ТБ виртуальной памяти, что происходит на Solaris, если вы хотите увеличить виртуальную память, вам нужно добавить пространство подкачки.

чтобы получить это:

ограничение количества потоков:

как это вычисляется:

и: x86_64 размер страницы (PAGE_SIZE) - 4K; Как и все другие модели, архитектуру x86_64 имеет стек ядра для каждого активного потока. Эти стеки потоков THREAD_SIZE (2*PAGE_SIZE) большие;

таким образом, на самом деле число не связано с ограничением размера стека памяти потока ( ulimit -s ).

P. S: ограничение стога памяти потока 10M внутри моя RHEL VM, а для памяти 1.5 G Эта VM может позволить себе только 150 потоков?

Это, вероятно, не должно иметь значения. Вы получите гораздо лучшую производительность, разрабатывая свой алгоритм для использования фиксированного количества потоков (например, 4 или 8, Если у вас есть 4 или 8 процессоров). Вы можете сделать это с рабочими очередями, асинхронным вводом-выводом или чем-то вроде libevent.

использовать nbio неблокирующий ввод-вывод библиотека или что-то еще, если вам нужно больше потоков для выполнения вызовов ввода-вывода, которые блокируют

проверьте размер стека на поток с помощью ulimit, в моем случае Redhat Linux 2.6:

каждый из потоков получит этот объем памяти (10 МБ), назначенный для его стека. С 32-битной программой и максимальным адресным пространством 4GB, это максимум только 4096Mb / 10MB = 409 потоков . Минус программный код, минус пространство кучи, вероятно, приведет к наблюдаемому максимуму. из 300 нитей.

вы должны быть в состоянии поднять это путем компиляции и запуска на 64bit или настройки ulimit-s 8192 или даже ulimit-s 4096. Но если это целесообразно - другое обсуждение.

зависит от вашей системы, просто напишите пример программы [ путем создания процессов в цикле ] и проверьте с помощью ps axo pid,ppid,rss,vsz,nlwp,cmd. Когда он больше не может создавать потоки, проверьте nlwp count [ nlwp-это количество потоков ] вуаля, вы получили свой дурацкий ответ вместо того, чтобы проходить через книги

для тех, кто смотрит на это сейчас, в системах systemd (в моем случае, в частности, Ubuntu 16.04) есть еще один предел, применяемый pids cgroup.максимальный параметр.

по умолчанию установлено значение 12,288 и может быть переопределено в /etc/systemd / logind.conf

другие советы по-прежнему применяются, включая pids_max, threads-max, max_maps_count, ulimits и т. д.

мы можем видеть максимальное количество потоков, определенных в следующем файле в linux

(Переключить) максимальное количество процессов, максимальное количество потоков, количество файлов, открытых процессом, и команду ulimit, чтобы изменить ограничения аппаратных ресурсов в Linux .

Подробное объяснение команды ulimit

ulimit используется для ресурсов, занятых процессом запуска оболочки, и может использоваться для установки системных ограничений.

в /etc/security/limits.conf Определено в документе
Ограничения.

Параметры команды описание пример
-H Установите жесткие ограничения ресурсов, после того, как набор не может быть увеличен. ulimit-Hs 64; ограничивает жесткие ресурсы, размер стека потока равен 64 КБ.
-S Установите ограничение мягких ресурсов, которое может быть увеличено после настройки, но не может превышать настройки жесткого ресурса. ulimit-Sn 32; ограничение мягких ресурсов, 32 файловых дескриптора.
-a Показать всю текущую информацию о лимите ulimit-a; отображать всю текущую информацию о лимитах
-c Размер самого большого файла ядра, в блоках ulimit - c без ограничений, без ограничений на размер сгенерированного файла ядра
-d Размер самого большого сегмента данных процесса, в килобайтах ulimit -d неограничен, размер сегмента данных процесса не ограничен
-f Максимальное количество файлов, которое может создать процесс, в блоках ulimit - f 2048; ограничить максимальный размер файла, который может создать процесс, до 2048 блоков.
-l Максимальный запираемый объем памяти, в килобайтах ulimit - l 32; ограничить максимальный объем блокируемой памяти до 32 Кбайт
-m Максимальный объем памяти в килобайтах ulimit-m не ограничен, нет ограничений на максимальную память
-n Максимальное количество файловых дескрипторов, которые могут быть открыты ulimit-n 128; ограничение до 128 файловых дескрипторов
-p Размер буфера трубы в килобайтах ulimit - p 512; ограничить размер буфера конвейера до 512 Кбайт
-s Размер стека потоков, в килобайтах ulimit - s 512; ограничить размер стека потока до 512 Кбайт
-t Максимальное время процессора в секундах ulimit - t не ограничено; нет ограничений по максимальному времени загрузки процессора
-u Максимальное количество процессов, доступных пользователям ulimit-u 64; ограничение пользователей на использование до 64 процессов
-v Максимально доступная виртуальная память процесса, в килобайтах ulimit - v 200000; ограничение максимально доступной виртуальной памяти до 200000 Кбайт

Мы можем использовать ulimit -a для просмотра всех ограничений нашей системы.

ulimit -a

Конечно, мы все знаем, что большинство настроек команды Linux временно действуют, а команда ulimit действует только для текущего терминала.

Если это должно быть постоянно эффективно, у нас есть два метода,

Один из них - написать команду для профиля и bashrc, что эквивалентно автоматическому изменению лимита при входе в систему.

Другой способ заключается в добавлении записи в /etc/security/limits.conf (для вступления в силу требуется перезапуск, а модуль ограничения используется при переходе в /etc/pam.d/).

Приложение к файлу Limits.conf

Формат изменения лимитов в /etc/security/limits.conf выглядит следующим образом

параметры описание
domino Имя пользователя или группы, начинающиеся с символа @, * означает всех пользователей
type Установить на жесткий или мягкий
item Укажите ресурс, который вы хотите ограничить. Такие как процессор, ядро ​​nproc или maxlogins
value Соответствует


Расчет максимального теоретического количества процессов в LINUX

  • Каждый процесс должен занимать две записи в таблице описания глобального сегмента GDT.

Локальная таблица описания сегмента LDT каждого процесса существует как независимый сегмент.В глобальной таблице описания сегмента GDT должна быть запись, указывающая на начальный адрес сегмента и указывающая длину сегмента и другие параметры. В дополнение к вышесказанному каждый процесс также имеет структуру TSS (сегмент состояния задачи). Поэтому каждый процесс должен занимать две записи в глобальной таблице описания сегментов GDT.

Ширина сегмента битов, используемого в качестве нижнего индекса таблицы GDT в регистре сегментов, составляет 13 битов, поэтому может быть 2 1 3 = 8192 Описание предметов.

За исключением некоторых системных издержек (например, элементы 2 и 3 в GDT используются для сегмента кода и сегмента данных ядра, элементы 4 и 5 всегда используются для сегмента кода и сегмента данных текущего процесса, элемент 1 Всегда 0 и т. Д.), По-прежнему доступно 8180 записей, поэтому теоретически максимальное количество процессов в системе равно 8180 / 2 = 4090 。

Таким образом, теоретическое максимальное количество процессов в системе составляет 4090

Фактическое количество процессов, которые могут быть созданы в системе

Ядро Linux использует значение идентификации процесса (PID) для идентификации процесса, PID - это число, бит типа pid_t, на самом деле int

Для обеспечения совместимости со старыми версиями Unix или Linux максимальное значение PID по умолчанию установлено равным 32768 (максимальное значение short int).

Можно использовать cat /proc/sys/kernel/pid_max Для просмотра фактического значения количества процессов, которые могут быть созданы в системе

cat /proc/sys/kernel/pid_max

После установки, хотя мы установили жесткое ограничение и мягкое ограничение числа процессов создания пользователя 65535, мы не можем использовать для создания 65535 процессов

Нам также нужно установить параметр ядра kernel.pid_max в Linux. Этот параметр по умолчанию равен 32768.

Таким образом, даже если используется учетная запись root, этот параметр ядра не задан, и максимальное количество процессов, которое может быть создано всей системой, равно 32768, поэтому нам необходимо установить следующее:

Максимальное количество потоков одного процесса в системе Linux имеет максимальное ограничение PTHREAD_THREADS_MAX

Этот предел может быть /usr/include/bits/local_lim.h Посмотреть в
Для linuxthreads это значение обычно составляет 1024, для nptl нет жесткого ограничения, ограничивается только системными ресурсами.

Ресурсы этой системы в основном представляют собой память, занятую стеком потоков. Используйте ulimit -s для просмотра размера стека потоков по умолчанию. В общем, это значение 8M=8192KB


Вы можете написать простой код, чтобы проверить, сколько потоков можно создать.


Эксперименты показывают, что в нашей системе (Ubuntu-14.04-LTS-64bit) на linuxthreads можно создать максимум 381 поток, после чего он вернется в EAGAIN.

Максимальное количество потоков, которое теоретически может создать отдельный процесс в Linux

В 32-битной системе можно использовать 381 поток. Это значение полностью согласуется с теорией, поскольку пользовательское пространство процесса в 32-битной Linux - это 3G, что составляет 3072M. 3072 M / 8 M = 384 Но на самом деле сегмент кода и сегмент данных также занимают некоторое пространство.Это значение должно быть округлено до 383, а затем вычтено из основного потока, чтобы получить 382.

Так почему же на linuxthreads есть одна нить? Это правильно, потому что linuxthreads также нуждается в потоке управления

Чтобы преодолеть ограничение памяти, есть два метода

использование ulimit -s 1024 Уменьшите размер стека по умолчанию

вызов pthread_create Время с pthread_attr_getstacksize Установить меньший размер стека

Следует отметить, что даже это не может нарушить жесткий предел 1024 потоков, если библиотека C не будет перекомпилирована

Максимальное количество файловых файловых дескрипторов системы

/ proc / sys / fs / file-max определяет общесистемное количество дескрипторов файлов, которые могут быть открыты всеми процессами (системный уровень, уровень ядра).

The value in file-max denotes the maximum number of file handles that the Linux kernel will allocate).

Для ядер 2.2 также необходимо учитывать inode-max. Как правило, inode-max устанавливается в 4 раза больше, чем file-max. Для ядер 2.4 и новее нет файла inode-max.

Посмотреть актуальное значение


Вы можете использовать cat / proc / sys / fs / file-max для просмотра количества дескрипторов файлов, которые могут быть открыты одним процессом в текущей системе.
186405

Настроить

nr_open - максимальное количество файлов, которое может быть выделено одним процессом

Максимальное количество файловых дескрипторов, поддерживаемых ядром, то есть максимальное количество файловых дескрипторов, используемых процессом

the maximum number of files that can be opened by process。


Nofile обрабатывает максимальное количество дескрипторов открытых файлов

Посмотреть актуальное значение


Конечно, представление по умолчанию - это мягкое ограничение мягкого ограничения ресурса. Если вы хотите просмотреть максимальное количество открытых символов описания файла процесса, поддерживаемых аппаратным обеспечением системы, вы можете использовать ulimit -Hn


Настроить

по ulimit -Sn Установите мягкое ограничение максимального числа дескрипторов открытых файлов. Обратите внимание, что мягкое ограничение не может превышать жесткое ограничение (ulimit -Hn может просматривать жесткое ограничение)

Кроме того, ulimit -n по умолчанию просматривает мягкий предел, но ulimit -n 1800000 устанавливает мягкий и жесткий лимит одновременно.

Для пользователей без полномочий root вы можете установить только жесткий предел, меньший, чем исходный.

Вышеуказанный метод является только временным, выход из системы и вход в систему будут недействительными, и жесткий предел не может быть увеличен, только мягкий предел может быть изменен в пределах жесткого ограничения.

Чтобы сделать изменение постоянным и эффективным, вам нужно установить его в /etc/security/limits.conf (требуется разрешение root), вы можете добавить следующие две строки, указывающие, что мягкое ограничение максимального числа дескрипторов открытых файлов для пользовательского канала составляет 1800000, жесткое ограничение 2000000. Для вступления в силу следующих настроек необходимо выйти и войти снова:

Еще одна вещь, которую следует отметить при установке жесткого предела nofile, заключается в том, что жесткий предел не может быть больше, чем / proc / sys / fs / nr_open. Если жесткий предел больше, чем nr_open, вы не сможете войти в систему после выхода из системы.


Значение nr_open можно изменить:

Связь между file-max, nr_open, onfile

Для ограничения максимального количества файлов, открытых пользователем, nofile, соответствующий limit.conf, будь то руководство пользователя или файл, является всего лишь предложением

Фактически это соответствует максимальному количеству файлов, которые могут быть открыты одним процессом. Обычно, чтобы избежать проблем, мы хотим снять его ограничение.

Согласно руководству пользователя, «значения -1, неограниченный или бесконечность, указывающие на отсутствие ограничений», -1, неограниченный и бесконечность, все указывают на отсутствие ограничений

Однако, когда вы фактически установите nofile на это значение, вы обнаружите, что не можете войти в систему при перезапуске.

Видно, что у nofile есть верхний предел и тест ulimit:

bash: ulimit: открытые файлы: невозможно изменить ограничение: операция запрещена


Напишите простой цикл for, чтобы получить:

Затем выполните ulimit -n, и вы увидите, что 1048576 является максимальным значением nofile, но почему это значение?

1024 ∗ 1024 = 1048576 Конечно, яиц мало используют.

После повторной трассировки мы обнаружим, что это значение фактически определяется параметром ядра nr_open:


На этом этапе мы поговорим о nr_open и file-max. Когда дело доходит до установки максимального количества файлов в Интернете, в некоторых публикациях также иногда говорится, что file-max необходимо изменить. Буквально, file-max действительно соответствует максимальному количеству файлов. Объяснение двух в документации ядра Linux:

  • file-max:
    The value in file-max denotes the maximum number of file-
    handles that the Linux kernel will allocate. When you get lots
    of error messages about running out of file handles, you might
    want to increase this limit

Выполните: grep -r MemTotal / proc / meminfo | awk ‘’, вы можете видеть, что это похоже на file-max;


  • nr_open:
    This denotes the maximum number of file-handles a process can
    allocate. Default value is 1024*1024 (1048576) which should be
    enough for most machines. Actual limit depends on RLIMIT_NOFILE
    resource limit.

файловые дескрипторы (то есть файловые дескрипторы), тогда в UNIX / LINUX мы более подвержены файловому дескриптору (FD, т.е. файловые дескрипторы), кажется, что файловый дескриптор в Windows - это материал, похожий на файл-дискриптор Но мы говорим о Linux, а затем Google, мы можем быть точными в разнице между этими двумя понятиями на языке c,

Согласно их обсуждению, дескриптор файла должен быть объектом высокого уровня, который вызывается с использованием таких функций, как fopen и fread, а FD является базовым объектом, который можно вызывать с помощью таких функций, как open и read.

На этом этапе мы должны сделать грубый вывод: File-max - это максимальное количество файлов, которое может быть выделено ядром, а nr_open - это максимальное количество файлов, которые могут быть выделены одним процессом, поэтому, когда мы используем ulimit или limit.conf для установки, если Если вы хотите превысить значение по умолчанию 1048576, вам нужно увеличить значение nr_open (sysctl -w fs.nr_open = 100000000 или записать его непосредственно в файл sysctl.conf). Конечно, должно хватить максимального числа открытых файловых дескрипторов одного уровня на уровне миллиона. ,

Количество файловых дескрипторов, открытых всеми процессами, не может превышать / proc / sys / fs / file-max

Количество файловых дескрипторов, открытых одним процессом, не может превышать мягкое ограничение nofile в пользовательском ограничении

Мягкий предел Nofile не может превышать его жесткий предел

жесткий предел nofile не может превышать / proc / sys / fs / nr_open

Основное отличие ядра 2.4 от ядра 2.6

В типичной системе с ядром 2.4 (AS3 / RH9) потоки реализованы с облегченными процессами. Каждый поток занимает идентификатор процесса. В программе сервера, если он сталкивается с доступом с высокой скоростью кликов, он вызывает переполнение таблицы процессов. Чтобы поддерживать переполненную таблицу процессов, система будет периодически приостанавливать обслуживание, и ядро ​​2.6 не будет вызывать проблему переполнения таблицы процессов из-за создания и уничтожения большого количества потоков.

Стек потока должен быть освобожден, когда поток заканчивается

Другими словами, функция потока должна вызывать pthread_exit () для завершения, иначе она не будет освобождена до тех пор, пока не прекратится выполнение основной функции процесса, особенно в среде ядра 2.6, скорость создания потока будет высокой, а память случайно израсходована. Это среда ядра 2.4. Потому что ядро ​​2.4 создает процессы, а скорость создания потоков на несколько порядков ниже, чем в ядре 2.6. В частности, на 64-разрядных процессорах скорость создания потоков в ядре 2.6 еще выше, если он слишком быстрый, лучше добавить usleep (), чтобы сделать паузу на некоторое время.

Не создавайте резьбовые приложения, требующие блокировки

Только те программы, которые не нуждаются в мьютексах, могут максимально использовать преимущества потокового программирования, в противном случае оно будет только медленнее. Ядро 2.6 является преимущественным ядром, и вероятность разделения конфликтов между потоками намного выше, чем в среде ядра 2.4. Обратите внимание на безопасность потоков. В противном случае даже один ЦП может привести к несинхронизации некоторой необъяснимой памяти (кэш-память ЦП и содержимое основной памяти несовместимы). Новый ЦП Intel использует архитектуру NUMA для повышения производительности. Вам следует обратить внимание, чтобы избежать недостатков в программировании потоков.

Максимальное количество одновременных потоков и памяти для однопроцессного сервера

Примечание 1

Вентиляторы BSD в устройстве использовали ноутбук AMD64 для запуска небольшой программы для проверки скорости создания потока (phread_detach () сразу после создания потока, а затем pthread_exit (), всего 1 миллион потоков). Тот же исходный код OpenBSD был в 3 раза быстрее, чем FreeBSD Когда OpenBSD сошел с ума?

Читайте также: