Maksymalna liczba wątków na proces w systemie Linux?

245

Jaka jest maksymalna liczba wątków, które można utworzyć w procesie pod Linuksem?

Jak (jeśli to możliwe) można zmodyfikować tę wartość?


źródło

Odpowiedzi:

247

Linux nie ma osobnego limitu wątków na limit procesów, a jedynie limit całkowitej liczby procesów w systemie (wątki to w zasadzie tylko procesy ze wspólną przestrzenią adresową w systemie Linux), które można wyświetlić w następujący sposób:

cat /proc/sys/kernel/threads-max

Domyślnie jest to liczba stron pamięci / 4. Możesz to zwiększyć w następujący sposób:

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

Istnieje również ograniczenie liczby procesów (a tym samym wątków), które może utworzyć pojedynczy użytkownik, zobacz ulimit/getrlimitszczegóły dotyczące tych ograniczeń.

Robert Gamble
źródło
3
Limit w / proc / sys / vm / max_map_count może również ograniczać liczbę wątków. Zwiększenie tego limitu powinno być bezpieczne, jeśli go uderzysz.
Mikko Rantalainen
1
Robert: Linux implementuje pośrednio ograniczenia na proces. Sprawdź moją odpowiedź, aby poznać szczegóły;)
codersofthedark
Próbuję to zmienić na moim Ubuntu 12.04 i nie zmieni się to z twoim poleceniem. Próbowałem także vi, aby to zmienić, ale otrzymuję, E667: Fsync failedgdy próbuję oszczędzać na vi.
Siddharth
4
@dragosrsupercool maksymalny wątek jest obliczany na podstawie całkowitej pamięci RAM, bez pamięci wirtualnej
c4f4t0r 11.11.13
1
Wielkość stosu na wątek (domyślna w systemie) jest bardziej prawdopodobna niż limit. Zmniejszenie rozmiaru stosu na wątek jest sposobem na zwiększenie całkowitej liczby wątków (choć rzadko jest to dobry pomysł).
Randy Howard
67

Błędem jest twierdzenie, że LINUX nie ma osobnych wątków na limit procesu.

Linux implementuje maksymalną liczbę wątków na proces pośrednio !!

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

Tak więc liczbę wątków na proces można zwiększyć, zwiększając całkowitą pamięć wirtualną lub zmniejszając rozmiar stosu. Jednak zbyt duże zmniejszenie rozmiaru stosu może prowadzić do niepowodzenia kodu z powodu przepełnienia stosu, podczas gdy maksymalna pamięć wirtualna jest równa pamięci wymiany.

Sprawdź swoją maszynę:

Całkowita pamięć wirtualna: ulimit -v(domyślnie jest nieograniczona, dlatego musisz zwiększyć pamięć wymiany, aby to zwiększyć)

Całkowity rozmiar stosu: ulimit -s(domyślnie jest to 8 Mb)

Polecenie, aby zwiększyć te wartości:

ulimit -s newvalue

ulimit -v newvalue

* Zastąp nową wartość wartością, którą chcesz ustawić jako limit.

Bibliografia:

http://dustycodes.wordpress.com/2012/02/09/increase-number-of-threads-per-process/

codersofthedark
źródło
11
Z wyjątkiem 3 drobnych szczegółów: 1. Linux tego nie robi, obecność stosów oraz fakt, że pamięć i przestrzeń adresowa są skończonych rozmiarów, nie ma z tym nic wspólnego. 2. Podczas tworzenia musisz określić stos wątku, niezależnie od tego ulimit -s. Jest bardzo możliwe (nie sensowne, ale możliwe), aby utworzyć tyle wątków, ile jest możliwych identyfikatorów wątków. W 64-bitowym systemie Linux nawet łatwiej jest „stworzyć” więcej wątków niż ich identyfikatory (oczywiście nie jest to możliwe, ale jeśli chodzi o stos, to jest). 3. Rezerwa stosu, zatwierdzanie i VM to różne rzeczy, szczególnie z OC.
Damon
Tak, aby zwiększyć liczbę wątków, musisz zwiększyć pamięć wirtualną lub zmniejszyć rozmiar stosu. W Raspberry Pi nie znalazłem sposobu na zwiększenie pamięci wirtualnej, jeśli zmniejszysz rozmiar stosu z domyślnych 8 MB do 1 MB Prawdopodobnie uzyskasz więcej niż 1000 wątków na proces, ale zmniejszysz rozmiar stosu za pomocą polecenia „ulimit -s” zrób to dla wszystkich wątków. Tak więc moim rozwiązaniem było użycie instancji „pthread_t” „klasa wątku”, ponieważ pthread_t pozwala mi ustawić rozmiar stosu dla każdego wątku. Wreszcie jestem w stanie zarchiwizować ponad 1000 wątków na proces w Raspberry Pi każdy z 1 MB stosu
Deulis
43

W praktyce limit jest zwykle określany przez przestrzeń stosu. Jeśli każdy wątek otrzyma stos 1 MB (nie pamiętam, czy jest to domyślny w systemie Linux), w systemie 32-bitowym zabraknie przestrzeni adresowej po 3000 wątków (przy założeniu, że ostatni GB jest zarezerwowany dla jądra) .

Jednak najprawdopodobniej doświadczysz strasznej wydajności, jeśli użyjesz więcej niż kilkudziesięciu wątków. Wcześniej czy później pojawi się zbyt wiele narzutu przełączania kontekstu, zbyt dużego narzutu w harmonogramie i tak dalej. (Utworzenie dużej liczby wątków nie tylko zużywa dużo pamięci. Ale wiele wątków przy faktycznej pracy spowolni cię, gdy będą walczyć o dostępny czas procesora)

Co robisz, gdy ten limit jest nawet istotny?

jalf
źródło
3
1 MB na wątek na stos jest dość wysoki, wiele programów nie potrzebuje nigdzie w pobliżu tak dużej przestrzeni stosu. Spektakl ma być oparty na liczbie przypisanymi procesów, a nie liczby wątków, które istnieją. Mam teraz maszynę działającą z ponad 1200 wątkami i obciążeniem 0,40.
Robert Gamble,
13
wydajność zależy od tego, co robią wątki. możesz przejść znacznie wyżej niż kilkadziesiąt, jeśli nie robią wiele, a zatem mniej zmieniają kontekst.
Corey Goldberg,
stos rośnie dynamicznie, tylko strona początkowa przydzielana jest poza batem
Michael Pankov
28

prawidłowe 100k wątków na Linuksie:

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

Aktualizacja 2018 od @ Thomas, na systemach systemowych:

/etc/systemd/logind.conf: UserTasksMax=100000
Vladimir Kunschikov
źródło
4
Dziękuję, w końcu pozwoliło mi to przełamać liczbę wątków Java 32k.
berezovskyi
1
Nie działa dla mnie: $ ulimit -s 100000 $ ulimit -i 63645 $ cat / proc / sys / kernel / thread-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: nie można utworzyć nowego natywnego wątku w java.lang.Thread.start0 (Metoda rodzima) w java.lang.Thread.start (Thread.java:717) w ThreadCreation.main ( ThreadCreation.java:15)
Martin Vysny,
@MartinVysny ulimit -s = rozmiar gwintu w kb. więc próbujesz utworzyć wątki o rozmiarze stosu 100 MB.
Vladimir Kunschikov
dodał (a) twoją sugestię bez sprawdzania @ Thomas, dzięki za opinię.
Vladimir Kunschikov
2
@VladimirKunschikov Dzięki kolego, twoje rozwiązanie naprawdę działało, a dzięki Thomasowi, aby dodać tę dodatkową linię, mogę potwierdzić, że nie zadziała bez tej linii.
BillHoo,
14

@dragosrsupercool

Linux nie używa pamięci wirtualnej do obliczenia maksymalnej liczby wątków, ale fizyczny RAM zainstalowany w systemie

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

http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/

jądro / 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);

Tak więc maksymalna liczba wątków różni się w zależności od systemu, ponieważ zainstalowany RAM może mieć różne rozmiary, wiem, że Linux nie musi zwiększać pamięci wirtualnej, ponieważ w 32 bitach mamy 3 GB na miejsce użytkownika i 1 GB na jądro, w wersji 64-bitowej mamy 128 TB pamięci wirtualnej, co dzieje się w systemie Solaris, jeśli chcesz zwiększyć pamięć wirtualną, musisz dodać przestrzeń wymiany.

c4f4t0r
źródło
11

Aby go odzyskać:

cat /proc/sys/kernel/threads-max

Aby ustawić:

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

123456789 = Liczba wątków

Vincent Van Den Berghe
źródło
Otrzymuję odmowę dostępu podczas próby pisania, nawet z rootem.
Kim
Minęło prawie dziesięć lat, odkąd to opublikowano. Nie jestem na bieżąco z obecnym stanem rzeczy, ale wiele mogło się zmienić (i prawdopodobnie zmieniło) ...
Vincent Van Den Berghe
problem z perm-deny może być >częścią append ( ) traci sudo: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
dwanderson
10

Limit liczby wątków:

$ cat /proc/sys/kernel/threads-max 

Jak to jest obliczane:

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

oraz: rozmiar strony x86_64 (PAGE_SIZE) to 4K; Podobnie jak wszystkie inne architektury, x86_64 ma stos jądra dla każdego aktywnego wątku. Te stosy wątków są duże THREAD_SIZE (2 * PAGE_SIZE);

dla wiadomości:

cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';

tak więc liczba ta nie jest związana z ograniczeniem rozmiaru stosu pamięci wątków ( ulimit -s).

PS: ograniczenie stosu pamięci wątków w mojej maszynie wirtualnej rhel wynosi 10 MB, a dla pamięci 1,5G ta maszyna wirtualna może sobie pozwolić tylko na 150 wątków?

Albert Kong
źródło
5

Dla każdego, kto na to teraz patrzy, w systemach systemowych (w moim przypadku, szczególnie Ubuntu 16.04) istnieje inny limit narzucony przez parametr cgroup pids.max.

Domyślnie jest ustawiona na 12 288 i można ją przesłonić w /etc/systemd/logind.conf

Nadal obowiązują inne porady, w tym pids_max, thread-max, max_maps_count, ulimits itp.

Trent Lloyd
źródło
5

sprawdź rozmiar stosu na wątek za pomocą ulimit, w moim przypadku Redhat Linux 2.6:

    ulimit -a
...
    stack size              (kbytes, -s) 10240

Każdy twój wątek otrzyma taką ilość pamięci (10 MB) przypisaną do stosu. Przy 32-bitowym programie i maksymalnej przestrzeni adresowej 4 GB, to maksymalnie 4096 MB / 10 MB = 409 wątków !!! Minusowy kod programu minus minus sterty prawdopodobnie doprowadzi do zaobserwowanego maks. z 300 wątków.

Powinieneś być w stanie to podnieść, kompilując i uruchamiając na 64bit lub ustawiając ulimit -s 8192 lub nawet ulimit -s 4096. Ale jeśli jest to wskazane, jest kolejna dyskusja ...

Axel Podehl
źródło
4

To chyba nie powinno mieć znaczenia. Będziesz uzyskiwać znacznie lepszą wydajność, projektując algorytm tak, aby używał stałej liczby wątków (np. 4 lub 8, jeśli masz 4 lub 8 procesorów). Możesz to zrobić za pomocą kolejek roboczych, asynchronicznego We / Wy lub czegoś takiego jak libevent.

twk
źródło
3
Celem wielowątkowości jest nie tylko wydajność. Na przykład nasłuchujesz 10 portów z systemem blokującym na 4 rdzeniowym procesorze. W tym przykładzie nie ma znaczenia 4.
obayhan
3

Użyj nbio nieblokującej biblioteki we / wy lub cokolwiek innego, jeśli potrzebujesz więcej wątków do wykonywania wywołań tego bloku

wefeqfw
źródło
2

Zależy od twojego systemu, po prostu napisz przykładowy program [tworząc procesy w pętli] i sprawdź używając ps axo pid, ppid, rss, vsz, nlwp, cmd. Gdy nie będzie już można tworzyć wątków, sprawdź liczbę nlwp [nlwp to liczba wątków] voila, masz głupią odpowiedź zamiast przechodzić przez książki

wyniki
źródło
1

Aby ustawić na stałe,

vim /etc/sysctl.conf

i dodaj

kernel.threads-max = "value"
Matteo Zocca
źródło
0

Widzimy maksymalną liczbę wątków zdefiniowanych w poniższym pliku w systemie Linux

cat / proc / sys / kernel / Thread-max

(LUB)

sysctl -a | grep wątki-max

KrishnaKumar Madagani
źródło
0

Możesz zobaczyć bieżącą wartość za pomocą następującego polecenia cat / proc / sys / kernel / Thread-max

Możesz także ustawić wartość jak

echo 100500> / proc / sys / kernel / Thread-max

Ustawiona wartość zostanie sprawdzona na podstawie dostępnych stron pamięci RAM. Jeśli struktury wątków zajmują więcej niż 1/8) dostępnych stron pamięci RAM, maksymalna liczba wątków zostanie odpowiednio zmniejszona.

Arif
źródło
0

Tak, aby zwiększyć liczbę wątków, musisz zwiększyć pamięć wirtualną lub zmniejszyć rozmiar stosu. W Raspberry Pi nie znalazłem sposobu na zwiększenie pamięci wirtualnej, jeśli zmniejszysz rozmiar stosu z domyślnych 8 MB do 1 MB Prawdopodobnie uzyskasz więcej niż 1000 wątków na proces, ale zmniejszysz rozmiar stosu za pomocą polecenia „ulimit -s” zrób to dla wszystkich wątków. Tak więc moim rozwiązaniem było użycie instancji „pthread_t” „klasa wątku”, ponieważ pthread_t pozwala mi ustawić rozmiar stosu dla każdego wątku. Wreszcie jestem w stanie zarchiwizować ponad 1000 wątków na proces w Raspberry Pi, każdy z 1 MB stosu.

Deulis
źródło