Яка максимальна кількість потоків, які можна створити процесом під Linux?
Як (якщо можливо) можна змінити це значення?
Яка максимальна кількість потоків, які можна створити процесом під Linux?
Як (якщо можливо) можна змінити це значення?
Відповіді:
У Linux немає окремих потоків на обмеження процесу, а лише обмеження на загальну кількість процесів у системі (потоки - це по суті просто процеси з спільним адресним простором в Linux), які ви можете переглядати так:
cat /proc/sys/kernel/threads-max
За замовчуванням - кількість сторінок пам'яті / 4. Ви можете збільшити це так:
echo 100000 > /proc/sys/kernel/threads-max
Також існує обмеження кількості процесів (і, отже, потоків), які може створити один користувач, див. ulimit/getrlimit
Подробиці щодо цих обмежень.
E667: Fsync failed
коли намагаюся заощадити на vi.
Це неправильно, якщо 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/
ulimit -s
. Дуже добре (не розумно, але можливо) створити стільки потоків, скільки можливих ідентифікаторів потоків. В умовах 64-бітного Linux навіть легко "можна" створити більше потоків, ніж ідентифікаторів потоків (звичайно, це неможливо, але що стосується стека, то це так). 3. Стек резерву, фіксація та VM - це різні речі, особливо з OC.
На практиці обмеження зазвичай визначається простором стеку. Якщо кожен потік отримує стек розміром 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-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, якщо ви хочете збільшити віртуальну пам’ять, вам потрібно додати місця для заміни.
Щоб отримати його:
cat /proc/sys/kernel/threads-max
Щоб встановити його:
echo 123456789 > /proc/sys/kernel/threads-max
123456789 = # ниток
>
) частина втрачає sudo
: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
Ліміт кількості ниток:
$ 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 потоків?
Для тих, хто зараз дивиться на це, у системних системах (у моєму випадку, зокрема, Ubuntu 16.04) є ще одне обмеження, застосоване параметром cgroup pids.max.
За замовчуванням встановлено 12 288 і може бути замінено в /etc/systemd/logind.conf
Інші поради все ще застосовуються, включаючи pids_max, nit-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 процесорів). Це можна зробити за допомогою черг роботи, асинхронного вводу-виводу або чогось подібного до звільного.
Залежить від вашої системи, просто напишіть зразок програми [шляхом створення процесів у циклі] і перевірте, використовуючи ps axo pid, ppid, rss, vsz, nlwp, cmd. Коли він більше не може створювати теми, перевіряйте кількість nlwp [nlwp - це кількість потоків] voila, ви отримали свою дурну довідкову відповідь, а не через книги
Щоб налаштувати постійно,
vim /etc/sysctl.conf
і додати
kernel.threads-max = "value"
Ми можемо бачити максимальну кількість потоків, визначених у наступному файлі в Linux
cat / proc / sys / ядро / теми-макс
(АБО)
sysctl -a | греп-нитки-макс
Ви можете побачити поточне значення за допомогою наступних команд-cat / proc / sys / kernel / thread-max
Ви також можете встановити таке значення, як
echo 100500> / proc / sys / ядро / теми-макс
Встановлене вами значення буде перевірене на доступних сторінках оперативної пам’яті. Якщо структури потоків займають більше 1/8) доступних сторінок оперативної пам’яті, потокове значення max буде відповідно зменшено.
Так, для збільшення кількості потоків вам потрібно збільшити віртуальну пам'ять або зменшити розмір стека. У Raspberry Pi я не знайшов способу збільшити віртуальну пам'ять, якщо зменшити розмір стека з 8MB до 1МБ за замовчуванням Можливо, ви отримаєте більше 1000 потоків за процес, але зменшіть розмір стека за допомогою команди «ulimit -s» зробіть це для всіх потоків. Отже, моє рішення було використовувати екземпляр "pthread_t" "клас потоку", оскільки pthread_t дозволив мені встановити розмір стека на кожен потік. Нарешті, я маю можливість архівувати більше 1000 потоків за процес у Raspberry Pi, кожен з яких має 1 МБ стека.