Optimiere meinen Linux-Server für 10.000 Threads pro Prozess
Wie andere erklärten, ist dies im Allgemeinen falsch. Ein Thread ist eine kostspielige Ressource , insbesondere weil er über einen eigenen Aufrufstapel verfügt (normalerweise ein Megabyte) und weil es sich um eine vom Kernel planbare Aufgabe handelt. Threads sind noch teurer als geöffnete Dateideskriptoren .
Lesen Sie Betriebssysteme: Drei einfache Teile (frei herunterladbares Lehrbuch).
Als Faustregel gilt, dass Sie nicht viele Threads und schon gar nicht viele ausführbare Threads haben möchten. Die Anzahl der ausführbaren Threads sollte im Allgemeinen höchstens der Anzahl der Kerne (oder einem kleinen Vielfachen davon) entsprechen, also höchstens etwa einem Dutzend. Die Anzahl der Threads in einem Prozess kann etwas größer sein. Wenn Sie also keinen sehr expansiven Server haben (mit vielen Prozessorsockeln und -kernen), möchten Sie nicht mehr als ein Dutzend ausführbare Threads und hundert Threads (die meisten davon inaktiv) in Ihrem Prozess (auf Ihrem Desktop) haben. .
Unter Linux sind Threads und Prozesse sehr ähnlich (da beide vom Klon (2) erstellt werden können ) und beide vom Kernel geplante Aufgaben sind. Tatsächlich plant der Kernel-Scheduler Aufgaben, die Threads innerhalb eines Multithread-Prozesses oder der einzelne Haupt-Thread eines Single-Thread-Prozesses (in diesem Fall werden Sie diesen einzelnen Thread als "Prozess" bezeichnen) oder Kernel-Threads sein können. Sie möchten wahrscheinlich nicht mehr als tausend planbare Aufgaben auf Ihrem Desktop-System haben.
Unter Linux ist ein Prozess einfach eine Gruppe von Threads, die denselben virtuellen Adressraum verwenden (und einige andere Dinge gemeinsam nutzen, z. B. die Dateideskriptortabelle usw.). Einige Prozesse haben nur einen Thread.
Ein virtueller Adressraum wird von Wikipedia als definiert
"die Reihe von Bereichen virtueller Adressen, die ein Betriebssystem einem Prozess zur Verfügung stellt"
(Siehe auch diese Antwort, in der erklärt wird, dass die Terminologie nicht universell ist und in einigen Microsoft-Dokumentationen eine andere und inkompatible Definition verwendet wird.)
Unter Linux ist proc (5) hilfreich, um den virtuellen Adressraum einiger Prozesse zu verstehen. Versuchen Sie beide
cat /proc/self/maps
und cat /proc/$$/maps
in einem Terminal. Siehe auch dies und pmap (1) & ps (1) & top (1) .
Alle User-Space-Programme werden in einem bestimmten Prozess ausgeführt und verwenden virtuellen Speicher, sodass jeder Prozess seinen eigenen virtuellen Adressraum hat. Der physische RAM ist eine Ressource, die vom Linux-Kernel verwaltet wird, und Anwendungen haben keinen direkten Zugriff auf den RAM (außer durch mmap (2) -ing /dev/mem
, siehe mem (4) ).
Ein Prozess verwendet also nicht direkt RAM. Es verwendet virtuellen Speicher und verfügt über einen eigenen virtuellen Adressraum. Der Kernel verwendet Paging physischen RAM zu verwalten Seiten und den virtuellen Adressraum und die Verfahren liefern Abstraktionen . Zu jeder Zeit (auch wenn Ihr Prozess inaktiv ist oder ausgeführt wird) kann der Kernel einige Seiten ausblenden (z. B. sie auf der Festplatte austauschen). Der Kernel konfiguriert die MMU (und behandelt Hardware- Ausnahmen bei Seitenfehlern in einigen Interrupt-Handlern , indem er entweder die Seite von der Festplatte abruft oder einen Segmentierungsfehler an den Prozess weitergibt, siehe Signal (7) ).
Sie könnten grüne Threads über System-Threads haben (aber grüne Thread-Bibliotheken sind schwer zu implementieren und zu debuggen). Schauen Sie sich die in Go verwendeten Goroutinen an, um ein ausgefallenes Beispiel zu finden. Siehe auch setcontext (3) .
Manchmal kann Ihr System mit Thrashing experimentieren . Dies geschieht, wenn der gesamte virtuelle Speicher (der von allen Prozessen benötigt wird) den verfügbaren physischen RAM um einen großen Faktor überschreitet. Dann reagiert Ihr Computer nicht mehr. Lesen Sie mehr über die Größe des residenten Satzes , das Anforderungs-Paging , den Arbeitssatz , die Speicherüberlastung und die ASLR .
Siehe auch -für Linux- Gabel (2) , Klon (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , Anmeldeinformationen (7) , pthreads (7) , Futex (7) , Fähigkeiten (7) .