Ausgabe
Es gibt viele Lösungen, die auf die Implementierung von “User-Space”-Threads ausgerichtet sind. Seien es golang.org-Goroutinen, Pythons grüne Threads, C#s Async, Erlangs Prozesse usw. Die Idee ist, eine gleichzeitige Programmierung auch mit einem einzigen oder einer begrenzten Anzahl von Threads zu ermöglichen.
Was ich nicht verstehe ist, warum sind die OS-Threads so teuer? Wie ich es sehe, müssen Sie auf jeden Fall den Stapel der Aufgabe (Betriebssystem-Thread oder Userland-Thread) speichern, der einige zehn Kilobyte groß ist, und Sie benötigen einen Planer, um zwischen zwei Aufgaben zu wechseln.
Das Betriebssystem stellt beide Funktionen kostenlos zur Verfügung. Warum sollten OS-Threads teurer sein als “grüne” Threads? Was ist der Grund für die angenommene Leistungsminderung, die durch einen dedizierten Betriebssystem-Thread für jede “Aufgabe” verursacht wird?
Lösung
Ich möchte die Antwort von Tudor ändern, was ein guter Ausgangspunkt ist. Es gibt zwei Haupt-Overheads von Threads:
- Sie zu starten und zu stoppen. Beinhaltet das Erstellen eines Stapels und von Kernel-Objekten. Beinhaltet Kernel-Übergänge und globale Kernel-Sperren.
- Halten ihren Stack herum.
(1) ist nur ein Problem, wenn Sie sie ständig erstellen und stoppen. Dies wird üblicherweise mithilfe von Thread-Pools gelöst. Ich halte dieses Problem für praktisch gelöst. Das Planen einer Aufgabe in einem Thread-Pool beinhaltet normalerweise keine Reise zum Kernel, was es sehr schnell macht. Der Overhead liegt in der Größenordnung von einigen verriegelten Speicheroperationen und einigen wenigen Zuweisungen.
(2) Dies wird nur wichtig, wenn Sie viele Threads haben (> 100 oder so). In diesem Fall ist async IO ein Mittel, um die Threads loszuwerden. Ich habe festgestellt, dass synchrone E / A, einschließlich Blockierung, etwas schneller ist als asynchrone E / A (Sie haben richtig gelesen: Sync E / A ist schneller), wenn Sie keine wahnsinnigen Mengen an Threads haben.
Beantwortet von – usr
Antwort geprüft von – Pedro (FixError Volunteer)