Was ist die maximale Anzahl von Threads, die von einem Prozess unter Linux erstellt werden können?
Wie kann dieser Wert (wenn möglich) geändert werden?
Was ist die maximale Anzahl von Threads, die von einem Prozess unter Linux erstellt werden können?
Wie kann dieser Wert (wenn möglich) geändert werden?
Antworten:
Linux hat kein separates Thread-Limit pro Prozess, sondern nur ein Limit für die Gesamtzahl der Prozesse auf dem System (Threads sind im Wesentlichen nur Prozesse mit einem gemeinsam genutzten Adressraum unter Linux), die Sie folgendermaßen anzeigen können:
cat /proc/sys/kernel/threads-max
Der Standardwert ist die Anzahl der Speicherseiten / 4. Sie können dies wie folgt erhöhen:
echo 100000 > /proc/sys/kernel/threads-max
Es gibt auch eine Begrenzung für die Anzahl der Prozesse (und damit für Threads), die ein einzelner Benutzer erstellen kann. Weitere ulimit/getrlimit
Informationen zu diesen Begrenzungen finden Sie hier.
E667: Fsync failed
wenn ich versuche, auf vi zu sparen.
Dies ist FALSCH zu sagen, dass LINUX keine separaten Threads pro Prozesslimit hat.
Linux implementiert indirekt die maximale Anzahl von Threads pro Prozess !!
number of threads = total virtual memory / (stack size*1024*1024)
Somit kann die Anzahl der Threads pro Prozess durch Erhöhen des gesamten virtuellen Speichers oder durch Verringern der Stapelgröße erhöht werden. Eine zu starke Verringerung der Stapelgröße kann jedoch zu einem Codefehler aufgrund eines Stapelüberlaufs führen, während der maximale virtuelle Speicher dem Auslagerungsspeicher entspricht.
Überprüfen Sie Ihre Maschine:
Gesamter virtueller Speicher: ulimit -v
(Standard ist unbegrenzt, daher müssen Sie den Auslagerungsspeicher erhöhen, um dies zu erhöhen.)
Gesamtstapelgröße: ulimit -s
(Standard ist 8 MB)
Befehl zum Erhöhen dieser Werte:
ulimit -s newvalue
ulimit -v newvalue
* Ersetzen Sie den neuen Wert durch den Wert, den Sie als Grenzwert festlegen möchten.
Verweise:
http://dustycodes.wordpress.com/2012/02/09/increasing-number-of-threads-per-process/
ulimit -s
. Es ist sehr gut möglich (nicht sinnvoll, aber möglich), so viele Threads zu erstellen, wie es mögliche Thread-IDs gibt. Unter 64-Bit-Linux ist es sogar leicht "möglich", mehr Threads zu erstellen, als Thread-IDs vorhanden sind (natürlich ist dies nicht möglich, aber was den Stack betrifft, ist dies der Fall). 3. Stack Reserve, Commit und VM sind verschiedene Dinge, besonders bei OC.
In der Praxis wird die Grenze normalerweise durch den Stapelraum bestimmt. Wenn jeder Thread einen 1-MB-Stapel erhält (ich kann mich nicht erinnern, ob dies unter Linux die Standardeinstellung ist), wird einem 32-Bit-System nach 3000 Threads der Adressraum ausgehen (vorausgesetzt, die letzte GB ist für den Kernel reserviert). .
Wenn Sie jedoch mehr als ein paar Dutzend Threads verwenden, werden Sie höchstwahrscheinlich eine schreckliche Leistung erleben. Früher oder später erhalten Sie zu viel Overhead beim Kontextwechsel, zu viel Overhead im Scheduler und so weiter. (Das Erstellen einer großen Anzahl von Threads verbraucht kaum mehr als viel Speicher. Aber viele Threads, die tatsächlich arbeiten müssen, werden Sie verlangsamen, da sie um die verfügbare CPU-Zeit kämpfen.)
Was machen Sie, wenn diese Grenze überhaupt relevant ist?
richtige 100k Threads unter 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
Update 2018 von @Thomas auf systemd-Systemen:
/etc/systemd/logind.conf: UserTasksMax=100000
@dragosrsupercool
Linux verwendet nicht den virtuellen Speicher, um das Maximum des Threads zu berechnen, sondern den auf dem System installierten physischen RAM
max_threads = totalram_pages / (8 * 8192 / 4096);
http://kavassalis.com/2011/03/linux-and-the-maximum-number-of-processes-threads/
kernel / 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);
Thread max unterscheidet sich also zwischen den einzelnen Systemen, da der installierte RAM unterschiedliche Größen haben kann. Ich weiß, dass Linux den virtuellen Speicher nicht vergrößern muss, da wir auf 32 Bit 3 GB für den Benutzerplatz und 1 GB für den Kernel haben. Auf 64-Bit haben wir 128 TB virtuellen Speicher, was unter Solaris der Fall ist. Wenn Sie den virtuellen Speicher erhöhen möchten, müssen Sie Swap-Speicher hinzufügen.
So rufen Sie es ab:
cat /proc/sys/kernel/threads-max
So stellen Sie es ein:
echo 123456789 > /proc/sys/kernel/threads-max
123456789 = Anzahl der Threads
>
) Teil verliert die sudo
: tryecho 12345678 | sudo tee -a /proc/sys/kernel/threads-max
Fadenzahlbegrenzung:
$ cat /proc/sys/kernel/threads-max
Wie es berechnet wird:
max_threads = mempages / (8 * THREAD_SIZE / PAGE_SIZE);
und: x86_64 Seitengröße (PAGE_SIZE) ist 4K; Wie alle anderen Architekturen verfügt x86_64 über einen Kernel-Stack für jeden aktiven Thread. Diese Thread-Stapel sind THREAD_SIZE (2 * PAGE_SIZE) groß.
für mempages:
cat /proc/zoneinfo | grep spanned | awk '{totalpages=totalpages+$2} END {print totalpages}';
Die Anzahl hängt also nicht mit der Beschränkung der Größe des Thread-Speicherstapels zusammen (ulimit -s
).
PS: Die Beschränkung des Thread-Speicherstapels in meiner Rhel-VM beträgt 10 MB. Für 1,5 GB Speicher kann sich diese VM nur 150 Threads leisten.
Für alle, die dies jetzt betrachten, gibt es auf systemd-Systemen (in meinem Fall speziell Ubuntu 16.04) eine weitere Begrenzung, die durch den Parameter cgroup pids.max erzwungen wird.
Dies ist standardmäßig auf 12.288 festgelegt und kann in /etc/systemd/logind.conf überschrieben werden
Es gelten weiterhin andere Hinweise, einschließlich pids_max, threads-max, max_maps_count, ulimits usw.
Überprüfen Sie die Stapelgröße pro Thread mit ulimit, in meinem Fall Redhat Linux 2.6:
ulimit -a
...
stack size (kbytes, -s) 10240
Jedem Ihrer Threads wird diese Speichermenge (10 MB) für seinen Stapel zugewiesen. Bei einem 32-Bit-Programm und einem maximalen Adressraum von 4 GB sind das maximal nur 4096 MB / 10 MB = 409 Threads !!! Minus Programmcode minus Heap-Space führt wahrscheinlich zu einem beobachteten max. von 300 Fäden.
Sie sollten in der Lage sein, dies zu erhöhen, indem Sie 64-Bit kompilieren und ausführen oder ulimit -s 8192 oder sogar ulimit -s 4096 einstellen. Aber wenn dies ratsam ist, ist eine andere Diskussion ...
Es sollte wahrscheinlich keine Rolle spielen. Sie werden eine viel bessere Leistung erzielen, wenn Sie Ihren Algorithmus so entwerfen, dass eine feste Anzahl von Threads verwendet wird (z. B. 4 oder 8, wenn Sie 4 oder 8 Prozessoren haben). Sie können dies mit Arbeitswarteschlangen, asynchronen E / A oder so etwas wie libevent tun.
Abhängig von Ihrem System schreiben Sie einfach ein Beispielprogramm [indem Sie Prozesse in einer Schleife erstellen] und überprüfen Sie es mit ps axo pid, ppid, rss, vsz, nlwp, cmd. Wenn es keine Threads mehr erstellen kann, überprüfe nlwp count [nlwp ist die Anzahl der Threads] voila du hast deine narrensichere Antwort erhalten, anstatt Bücher durchzugehen
Um dauerhaft einzustellen,
vim /etc/sysctl.conf
und hinzufügen
kernel.threads-max = "value"
Wir können die maximale Anzahl von Threads sehen, die in der folgenden Datei unter Linux definiert sind
cat / proc / sys / kernel / threads-max
(ODER)
sysctl -a | grep threads-max
Sie können den aktuellen Wert mit dem folgenden Befehl anzeigen: cat / proc / sys / kernel / threads-max
Sie können den Wert auch wie folgt einstellen
echo 100500> / proc / sys / kernel / threads-max
Der von Ihnen festgelegte Wert wird mit den verfügbaren RAM-Seiten verglichen. Wenn die Thread-Strukturen mehr als 1/8 der verfügbaren RAM-Seiten belegen, wird Thread-Max entsprechend reduziert.
Ja, um die Anzahl der Threads zu erhöhen, müssen Sie den virtuellen Speicher erhöhen oder die Stapelgröße verringern. In Raspberry Pi habe ich keine Möglichkeit gefunden, den virtuellen Speicher zu vergrößern, wenn die Stapelgröße von standardmäßig 8 MB auf 1 MB verringert wird. Es werden möglicherweise mehr als 1000 Threads pro Prozess angezeigt, aber die Stapelgröße wird mit dem Befehl "ulimit -s" verringert Machen Sie dies für alle Threads. Meine Lösung war also die Verwendung der Instanz "pthread_t" der "Thread-Klasse", da ich mit "pthread_t" die Stapelgröße für jeden Thread festlegen konnte. Schließlich kann ich in Raspberry Pi mehr als 1000 Threads pro Prozess mit jeweils 1 MB Stapel archivieren.