Jestem zwykłym użytkownikiem Go, więc weź to z odrobiną soli.
Wikipedia definiuje zielone wątki jako „wątki, które są planowane przez maszynę wirtualną (VM) zamiast natywnie przez podstawowy system operacyjny”. Zielone wątki emulują środowiska wielowątkowe bez polegania na natywnych możliwościach systemu operacyjnego i są zarządzane w przestrzeni użytkownika zamiast w przestrzeni jądra, umożliwiając im pracę w środowiskach, które nie obsługują wątków natywnych.
Go (a dokładniej dwie istniejące implementacje) jest językiem produkującym tylko kod macierzysty - nie używa maszyny wirtualnej. Ponadto harmonogram w bieżących implementacjach środowiska wykonawczego opiera się na wątkach na poziomie systemu operacyjnego (nawet gdy GOMAXPROCS = 1). Myślę więc, że mówienie o zielonych wątkach dla modelu Go jest trochę obelżywe.
Ludzie Go wymyślili termin „goroutine”, aby uniknąć pomyłek z innymi mechanizmami współbieżności (takimi jak coroutines lub wątki lub lekkie procesy).
Oczywiście Go obsługuje model wątków M: N, ale wygląda znacznie bliżej modelu procesu Erlang, niż modelu zielonego wątku Java.
Oto kilka zalet modelu Go w porównaniu z zielonymi wątkami (wdrożonymi we wczesnej JVM):
Można efektywnie wykorzystać wiele rdzeni lub procesorów, w przejrzysty sposób dla programisty. W Go programista powinien zadbać o współbieżność. Środowisko wykonawcze Go zajmie się równoległością. Implementacje zielonych wątków Java nie skalowały się na wielu rdzeniach ani procesorach.
Wywołania systemowe i C nie blokują harmonogramu (wszystkie wywołania systemowe, nie tylko te obsługujące zmultipleksowane We / Wy w pętlach zdarzeń). Implementacje zielonych wątków mogą blokować cały proces, gdy zostanie wykonane wywołanie systemowe.
Kopiowanie lub segmentowanie stosów. W Go nie ma potrzeby podawania maksymalnego rozmiaru stosu dla goroutine. Stos rośnie stopniowo, zależnie od potrzeb. Jedną konsekwencją jest to, że goroutine nie wymaga dużej ilości pamięci (4KB-8KB), więc ogromną liczbę z nich można z powodzeniem odrodzić. Dlatego stosowanie goroutine może być wszechobecne.
Teraz, aby odpowiedzieć na krytykę:
Dzięki Go nie musisz pisać harmonogramu przestrzeni użytkownika: jest on już dostarczany z środowiskiem uruchomieniowym. Jest to złożone oprogramowanie, ale jest to problem programistów Go, a nie użytkowników Go. Jego użycie jest przejrzyste dla użytkowników Go. Wśród programistów Go Dmitri Vyukov jest ekspertem w programowaniu bez blokady / oczekiwania i wydaje się, że jest szczególnie zainteresowany rozwiązaniem ewentualnych problemów z wydajnością harmonogramu. Obecna implementacja harmonogramu nie jest doskonała, ale ulegnie poprawie.
Synchronizacja wiąże się z problemami z wydajnością i złożonością: jest to częściowo prawdziwe również w przypadku Go. Należy jednak pamiętać, że model Go próbuje promować wykorzystanie kanałów i czysty rozkład programu w współbieżnych goroutynach, aby ograniczyć złożoność synchronizacji (tj. Współdzielenie danych przez komunikację, zamiast dzielenia pamięci do komunikacji). Nawiasem mówiąc, referencyjna implementacja Go zapewnia szereg narzędzi do rozwiązywania problemów z wydajnością i współbieżnością, takich jak profiler i wykrywacz wyścigów .
Jeśli chodzi o błąd strony i „fałszowanie wielu wątków”, zwróć uwagę, że Go może zaplanować goroutine na wiele wątków systemowych. Kiedy jeden wątek jest blokowany z jakiegokolwiek powodu (błąd strony, blokowanie wywołań systemowych), nie uniemożliwia to innym wątkom dalszego planowania i uruchamiania innych goroutine. Prawdą jest, że błąd strony zablokuje wątek systemu operacyjnego, a wszystkie goroutiny powinny być zaplanowane w tym wątku. Jednak w praktyce pamięć sterty Go nie powinna być wymieniana. Tak samo byłoby w Javie: śmieciowe języki i tak nie są dobrze przystosowane do pamięci wirtualnej. Jeśli Twój program musi w sposób płynny obsłużyć błąd strony, to prawdopodobnie dlatego, że musi zarządzać pamięcią zewnętrzną. W tym wypadku,
Więc IMO, goroutiny nie są zielonymi wątkami, a język Go i obecna implementacja w większości rozwiązuje te krytyki.