Czy baseny goroutine z Go-Lang są tylko zielonymi nitkami?

47

Komentator tutaj oferuje następujące krytykę zielonych wątków:

Początkowo zostałem sprzedany w modelu N: M jako środek programowania sterowanego zdarzeniami bez piekła zwrotnego. Możesz pisać kod, który wygląda jak stary kod proceduralny, ale pod nim jest magia, która używa przełączania zadań w przestrzeni użytkownika, gdy tylko coś się zablokuje. Brzmi wspaniale. Problem polega na tym, że rozwiązujemy złożoność z większą złożonością. swapcontext () i rodzina są dość nieruchome, złożoność pochodzi z innych niezamierzonych miejsc.

Nagle jesteś zmuszony napisać program planujący przestrzeń użytkownika i zgadnij, co naprawdę trudno napisać program planujący, który wykona lepszą robotę niż harmonogram Linuksa, który wymaga wielu lat wysiłku. Teraz chcesz, aby Twój harmonogram obsługiwał N zielonych wątków do M wątków fizycznych, więc musisz się martwić synchronizacją. Synchronizacja powoduje problemy z wydajnością, więc zaczynasz teraz, gdy jesteś w nowej, niezablokowanej króliczej nory. Budowanie poprawnego, wysoce współbieżnego harmonogramu nie jest łatwym zadaniem.

Kolejna krytyka jest tutaj :

Pojedynczy proces fałszowania wielu wątków ma wiele problemów. Jednym z nich jest to, że wszystkie sfałszowane wątki zatrzymują się na każdej stronie.

Moje pytanie brzmi - czy góraliny Go-Langa (dla domyślnej puli) to tylko zielone nici? Jeśli tak - czy odnoszą się do powyższej krytyki?

Sokole Oko
źródło

Odpowiedzi:

67

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.

Didier Spezia
źródło
1
Doskonała i szczegółowa odpowiedź na pytanie :)
Tuxdude
1
Podoba mi się ta odpowiedź, ale czy masz jakieś odniesienia do tego, jak / kiedy tworzone są wątki systemu operacyjnego?
Lars,
1
Jedną z największych wad Go Language jest to, że tworzy wątek jądra dla każdego blokującego wywołania systemowego!
user1870400,
8
Zauważ, że artykuł „zielony wątek” na Wikipedii został zmieniony na „wątki zaplanowane przez bibliotekę wykonawczą lub maszynę wirtualną (VM)”; co oznacza, że ​​zgodnie z tą definicją twoja odpowiedź nie byłaby już poprawna, ponieważ środowisko wykonawcze Go wykonuje planowanie / zarządzanie. Myślę, że bardziej pomocne jest zdefiniowanie zielonych wątków jako wątków przestrzeni użytkownika kontrastujących z wątkami systemu operacyjnego. A potem, tak, goroutiny to na pewno zielone nici.
mknecht
1
2. że @mknecht. Nie chodzi o maszynę wirtualną, chodzi o środowisko wykonawcze. I Go zdecydowanie ma środowisko uruchomieniowe. (który zarządza modelem wątków i odśmiecaniem).
Tim Harper