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ść?

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ń.


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/


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?


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

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.


11

Aby go odzyskać:

cat /proc/sys/kernel/threads-max

Aby ustawić:

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

123456789 = Liczba wątków


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?


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.


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 ...


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.


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


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



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


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.


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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.