Максимальна кількість потоків за один процес у Linux?


245

Яка максимальна кількість потоків, які можна створити процесом під Linux?

Як (якщо можливо) можна змінити це значення?

Відповіді:


247

У Linux немає окремих потоків на обмеження процесу, а лише обмеження на загальну кількість процесів у системі (потоки - це по суті просто процеси з спільним адресним простором в Linux), які ви можете переглядати так:

cat /proc/sys/kernel/threads-max

За замовчуванням - кількість сторінок пам'яті / 4. Ви можете збільшити це так:

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

Також існує обмеження кількості процесів (і, отже, потоків), які може створити один користувач, див. ulimit/getrlimitПодробиці щодо цих обмежень.


3
Обмеження в / proc / sys / vm / max_map_count також може обмежувати кількість потоків. Це повинно бути безпечним, щоб сильно збільшити цю межу, якщо вдарити її.
Мікко Ранталайнен

1
Роберт: Linux реалізує опосередковано обмеження на процес. Перевірте мою відповідь для деталей;)
codersofthedark

Я намагаюся змінити це на моєму ubuntu 12.04, і це не змінюється з вашою командою. Я також спробував vi змінити це, але отримую, E667: Fsync failedколи намагаюся заощадити на vi.
Сіддхарт

4
@dragosrsupercool максимальний потік обчислюється з використанням загальної оперативної пам’яті, віртуальної пам’яті немає
c4f4t0r

1
Кількість стека на один потік (за замовчуванням у вашій системі) швидше буде обмеженням, ніж будь-що інше. Зменшення розміру стека на одну нитку - це спосіб збільшити загальну кількість потоків (хоча це рідко є хорошою ідеєю).
Ренді Ховард

67

Це неправильно, якщо 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/


11
За винятком трьох дрібниць: 1. Linux цього не робить, наявність стеків та факт, що пам'ять та адресний простір обмеженого розміру, не мають нічого спільного. 2. Ви повинні вказати стек потоку під час його створення, це незалежно від ulimit -s. Дуже добре (не розумно, але можливо) створити стільки потоків, скільки можливих ідентифікаторів потоків. В умовах 64-бітного Linux навіть легко "можна" створити більше потоків, ніж ідентифікаторів потоків (звичайно, це неможливо, але що стосується стека, то це так). 3. Стек резерву, фіксація та VM - це різні речі, особливо з OC.
Деймон

Так, для збільшення кількості потоків вам потрібно збільшити віртуальну пам'ять або зменшити розмір стека. У Raspberry Pi я не знайшов спосіб збільшити віртуальну пам'ять, якщо зменшити розмір стека з 8 МБ до 1 МБ, можливо, ви отримаєте більше 1000 потоків за процес, але зменшіть розмір стека за допомогою команди «ulimit -s» зробіть це для всіх потоків. Отже, моє рішення було використовувати екземпляр "pthread_t" "клас потоку", оскільки pthread_t дозволив мені встановити розмір стека на кожен потік. Нарешті, я маю можливість архівувати більше 1000 потоків за один процес у Raspberry Pi, кожен з яких має 1 МБ стека
Deulis

43

На практиці обмеження зазвичай визначається простором стеку. Якщо кожен потік отримує стек розміром 1 Мб (я не можу пригадати, чи це за замовчуванням в Linux), то у вас 32-бітна система вичерпається з адресного простору після 3000 потоків (якщо припустити, що останній gb зарезервований для ядра) .

Однак ви, швидше за все, відчуєте жахливу ефективність, якщо використовуватимете кілька десятків ниток. Рано чи пізно ви отримуєте занадто багато режиму перемикання контексту, занадто багато накладних витрат у планувальнику тощо. (Створення великої кількості ниток робить трохи більше, ніж їсть багато пам’яті. Але багато ниток із фактичною роботою - це сповільнить вас, оскільки вони борються за доступний час процесора)

Що ви робите, коли ця межа навіть є актуальною?


3
1 Мб на потік для стека досить високий, багатьом програмам не потрібно десь поблизу такої великої кількості стеку. Продуктивність буде ґрунтуватися на кількості запущених процесів, а не на кількості потоків, що існують. Зараз у мене працює машина з 1200+ нитками з навантаженням 0,40.
Роберт Гембл

13
продуктивність залежить від того, що роблять нитки. ви можете піднятися набагато вище, ніж на кілька десятків, якщо вони не роблять багато, а значить, і менше перемикання контексту.
Корі Голдберг

стек динамічно зростає, лише початкова сторінка виділяється в офлайні
Михайло Паньков

28

належні 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

4
Дякую, що врешті-решт я дозволив мені пробити кількість потоків Java на 32 кб.
березівський

1
Не працює для мене: $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / ядро ​​/ теми-max 127626 $ cat / proc / sys / vm / max_map_count 600000 $ cat / proc / sys / kernel / pid_max 200000 $ java -Xmx4G -Xss256k -cp. ThreadCreation ... 11542 11543 java.lang.OutOfMemoryError: не вдається створити нову рідну нитку на java.lang.Thread.start0 (Native Method) на java.lang.Thread.start (Thread.java:717) на ThreadCreation.main ( ThreadCreation.java:15)
Мартін Висний

@MartinVysny ulimit -s = розмір нитки в кб. тому ви намагаєтеся створити теми з розміром стека 100MB.
Володимир Кунщиков

додав вашу пропозицію, не перевіряючи, @Thomas, все одно дякую за відгук.
Володимир Кунщиков

2
@VladimirKunschikov Спасибі приятелю, ваше рішення справді спрацювало, і дякую Томасу, що додав цей додатковий рядок, можу підтвердити, що він не буде працювати з цією лінією.
BillHoo

14

@dragosrsupercool

Linux не використовує віртуальну пам'ять для обчислення максимуму потоку, а фізичний таран, встановлений у системі

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

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-process-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);

Отже, макс потоку відрізняється між кожною системою, тому що встановлена ​​операційна пам'ять може бути різного розміру, я знаю, що Linux не потребує збільшення віртуальної пам’яті, тому що на 32 біт у нас є 3 ГБ для користувальницького простору та 1 ГБ для ядра, на 64 біті ми отримали 128 ТБ віртуальної пам’яті, що трапляється на Solaris, якщо ви хочете збільшити віртуальну пам’ять, вам потрібно додати місця для заміни.


11

Щоб отримати його:

cat /proc/sys/kernel/threads-max

Щоб встановити його:

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

123456789 = # ниток


Я отримую відмову в дозволі, коли намагаюся писати, навіть із коренем.
Кім

Що ж, минуло майже десятиліття з моменту публікації. Я не в курсі поточного стану речей, але багато що, можливо, змінилося (і, мабуть, було) ...
Вінсент Ван Ден Берге

проблема з perm-deny може бути додана ( >) частина втрачає sudo: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson

10

Ліміт кількості ниток:

$ 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 М у моїй програмі VM, а для пам’яті 1,5 Г ця ВМ може дозволити собі лише 150 потоків?


5

Для тих, хто зараз дивиться на це, у системних системах (у моєму випадку, зокрема, Ubuntu 16.04) є ще одне обмеження, застосоване параметром cgroup pids.max.

За замовчуванням встановлено 12 288 і може бути замінено в /etc/systemd/logind.conf

Інші поради все ще застосовуються, включаючи pids_max, nit-max, max_maps_count, ulimits тощо.


5

перевірити розмір стека на одну нитку за допомогою 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

Мабуть, це не має значення. Ви будете отримувати набагато кращі показники продуктивності свого алгоритму для використання фіксованої кількості потоків (наприклад, 4 або 8, якщо у вас є 4 або 8 процесорів). Це можна зробити за допомогою черг роботи, асинхронного вводу-виводу або чогось подібного до звільного.


3
Метою багатопотокової роботи є не тільки виконання. Наприклад, ви прослуховуєте 10 портів із системою блокування 4-ядерного процесора. У цьому прикладі немає сенсу 4.
Obayhan

3

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


2

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



0

Ми можемо бачити максимальну кількість потоків, визначених у наступному файлі в Linux

cat / proc / sys / ядро ​​/ теми-макс

(АБО)

sysctl -a | греп-нитки-макс


0

Ви можете побачити поточне значення за допомогою наступних команд-cat / proc / sys / kernel / thread-max

Ви також можете встановити таке значення, як

echo 100500> / proc / sys / ядро ​​/ теми-макс

Встановлене вами значення буде перевірене на доступних сторінках оперативної пам’яті. Якщо структури потоків займають більше 1/8) доступних сторінок оперативної пам’яті, потокове значення max буде відповідно зменшено.


0

Так, для збільшення кількості потоків вам потрібно збільшити віртуальну пам'ять або зменшити розмір стека. У Raspberry Pi я не знайшов способу збільшити віртуальну пам'ять, якщо зменшити розмір стека з 8MB до 1МБ за замовчуванням Можливо, ви отримаєте більше 1000 потоків за процес, але зменшіть розмір стека за допомогою команди «ulimit -s» зробіть це для всіх потоків. Отже, моє рішення було використовувати екземпляр "pthread_t" "клас потоку", оскільки pthread_t дозволив мені встановити розмір стека на кожен потік. Нарешті, я маю можливість архівувати більше 1000 потоків за процес у Raspberry Pi, кожен з яких має 1 МБ стека.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.