Ich bin nur ein gelegentlicher Go-Benutzer, nehmen Sie also Folgendes mit einem Körnchen Salz.
Wikipedia definiert grüne Threads als "Threads, die von einer virtuellen Maschine (VM) anstatt vom zugrunde liegenden Betriebssystem geplant werden". Grüne Threads emulieren Multithread-Umgebungen, ohne auf native Betriebssystemfunktionen angewiesen zu sein. Sie werden im Benutzerbereich statt im Kernel-Bereich verwaltet, sodass sie in Umgebungen ohne native Thread-Unterstützung arbeiten können.
Go (oder genauer gesagt die beiden vorhandenen Implementierungen) ist eine Sprache, die nur nativen Code erzeugt - es wird keine VM verwendet. Darüber hinaus stützt sich der Scheduler in den aktuellen Laufzeitimplementierungen auf Threads auf Betriebssystemebene (auch wenn GOMAXPROCS = 1 ist). Ich halte es daher für etwas missbräuchlich, über grüne Fäden für das Go-Modell zu sprechen.
Go-Leute haben den Begriff Goroutine geprägt, um Verwechslungen mit anderen Nebenläufigkeitsmechanismen (wie Coroutinen oder Threads oder Lightweight-Prozesse) zu vermeiden.
Natürlich unterstützt Go ein M: N-Threading-Modell, das dem Erlang-Prozessmodell jedoch viel näher kommt als dem Java-Green-Thread-Modell.
Hier sind einige Vorteile des Go-Modells gegenüber Green Threads (wie in früheren JVM-Versionen implementiert):
Mehrere Kerne oder CPUs können auf transparente Weise für den Entwickler effektiv genutzt werden. Bei Go sollte sich der Entwickler um die Parallelität kümmern. Die Go-Laufzeit sorgt für Parallelität. Java-Green-Threads-Implementierungen wurden nicht über mehrere Kerne oder CPUs skaliert.
System- und C-Aufrufe sind für den Scheduler nicht blockierend (alle Systemaufrufe, nicht nur diejenigen, die Multiplex-E / A in Ereignisschleifen unterstützen). Green-Threads-Implementierungen können den gesamten Prozess blockieren, wenn ein Systemaufruf blockiert wurde.
Kopieren oder segmentierte Stapel. In Go muss keine maximale Stapelgröße für die Goroutine angegeben werden. Der Stapel wächst schrittweise nach Bedarf. Eine Konsequenz ist, dass eine Goroutine nicht viel Speicher benötigt (4KB-8KB), so dass eine große Anzahl von ihnen glücklich erzeugt werden kann. Goroutine-Nutzung kann daher allgegenwärtig sein.
Um auf die Kritik einzugehen:
Mit Go müssen Sie keinen Userspace-Scheduler schreiben, der bereits mit der Laufzeit ausgeliefert wird. Es ist eine komplexe Software, aber es ist das Problem der Go-Entwickler, nicht der Go-Benutzer. Die Verwendung ist für Go-Benutzer transparent. Unter den Go-Entwicklern ist Dmitri Vyukov ein Experte für sperrenfreie / wartefreie Programmierung, und er scheint besonders daran interessiert zu sein, die möglichen Leistungsprobleme des Schedulers zu lösen. Die aktuelle Scheduler-Implementierung ist nicht perfekt, wird sich aber verbessern.
Die Synchronisierung bringt Leistungsprobleme und Komplexität mit sich. Dies gilt zum Teil auch für Go. Beachten Sie jedoch, dass das Go-Modell versucht, die Verwendung von Kanälen und eine saubere Zerlegung des Programms in gleichzeitigen Goroutinen zu fördern, um die Komplexität der Synchronisation zu begrenzen (dh Daten durch Kommunikation zu teilen, anstatt Speicher für die Kommunikation zu teilen). Übrigens bietet die Referenz-Go-Implementierung eine Reihe von Tools zur Behebung von Leistungs- und Nebenläufigkeitsproblemen, z. B. einen Profiler und einen Race Detector .
In Bezug auf Seitenfehler und das Fälschen mehrerer Threads beachten Sie bitte, dass Go Goroutine über mehrere System-Threads hinweg planen kann. Wenn ein Thread aus irgendeinem Grund blockiert wird (Seitenfehler, Blockieren von Systemaufrufen), verhindert dies nicht, dass die anderen Threads weiterhin andere Goroutinen planen und ausführen. Nun ist es wahr, dass ein Seitenfehler den Betriebssystem-Thread blockiert, mit allen Goroutinen, die für diesen Thread geplant werden sollen. In der Praxis sollte der Go-Heap-Speicher jedoch nicht ausgetauscht werden. Dies wäre auch in Java der Fall: Garbage Collected Languages nehmen den virtuellen Speicher ohnehin nicht sehr gut auf. Wenn Ihr Programm mit Seitenfehlern auf angemessene Weise umgehen muss, wenn dies wahrscheinlich daran liegt, dass ein Teil des Off-Heap-Speichers verwaltet werden muss. In diesem Fall,
Goroutinen sind also keine grünen Fäden, und die Go-Sprache und die derzeitige Implementierung richten sich hauptsächlich gegen diese Kritik.