Dlaczego nie zielone wątki?

33

Chociaż wiem, że pytania na ten temat zostały już omówione (np. Https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), nie wydaje mi się, żebym uzyskał zadowalającą odpowiedź .

Pytanie brzmi: dlaczego JVM nie obsługuje już zielonych wątków?

Mówi to na często zadawanych pytaniach w stylu Java :

Zielony wątek odnosi się do trybu działania wirtualnej maszyny Java (JVM), w którym cały kod jest wykonywany w jednym wątku systemu operacyjnego.

I to na java.sun.com :

Minusem jest to, że użycie zielonych wątków oznacza, że ​​wątki systemowe w systemie Linux nie są wykorzystywane, a zatem wirtualna maszyna Java nie jest skalowalna po dodaniu dodatkowych procesorów.

Wydaje mi się, że JVM może mieć pulę procesów systemowych równą liczbie rdzeni, a następnie uruchamiać na nim zielone wątki. Może to oferować duże korzyści, gdy masz bardzo dużą liczbę wątków, które często blokują (głównie dlatego, że bieżąca JVM ogranicza liczbę wątków).

Myśli?

redjamjar
źródło
5
Wydaje mi się pytanie: dlaczego zielone nici? Po co ponownie wprowadzać wielowątkowość, emulując ją na poziomie JVM za pomocą wielu procesów? Jest to bardzo bolesne i ogólne, ponieważ pozornie nie zyskuje, poza tym, że pozwala programistom być bardziej hojnym w spawnowaniu wątków (i nie jestem przekonany, że to zaleta).
4
Chodzi o współbieżny model programowania, który można skalować. Obecnie w Javie, jeśli chcesz skalowalności, przełączasz się na NIO z własną pulą wątków. Przynajmniej tak rozumiem.
redjamjar,
3
Obecność takich rzeczy jak < akka.io >, które obsługują lekkie wątki, również każe mi myśleć, że jest taka potrzeba. Właściwie właśnie znalazłem tutaj całkiem dobrą dyskusję < stackoverflow.com/questions/7458782/… >
redjamjar,
2
@delnan Ponieważ zmiana kontekstu dla rodzimych kosztów wątków. Zielone wątki mają znacznie mniejszy narzut na przełączanie kontekstu i synchronizacje międzyprocesowe. Ponadto ilość zielonych wątków jest praktycznie nieograniczona (może to być setki tysięcy bez nadmiernego obciążenia procesu VM), podczas gdy ilość wątków rodzimych jest ograniczona przez system operacyjny i pamięć.
permeakra
Minęło dużo czasu, zanim JVM bezpośrednio obsługiwał wątki natywne. Do tego czasu zielone nici były rozwiązaniem pośrednim.
Thorbjørn Ravn Andersen

Odpowiedzi:

29

Pamiętam, jak JVM porzuciła zielone wątki i przeniosła się do wątków rodzimych. Stało się tak z dwóch prostych powodów: zielone wątki były szczerze mówiąc śmieciami, a także trzeba było wspierać procesory wielordzeniowe przy ograniczonym nakładzie pracy programistów dostępnym w firmie Sun.

Szkoda - zielone wątki zapewniają znacznie lepszą abstrakcję, pozwalając, aby współbieżność była użytecznym narzędziem, a nie przeszkodą. Ale zielone nici nie przydadzą się, jeśli nie uda się pokonać kilku przeszkód:

  • muszą używać wszystkich dostępnych rdzeni procesorów

  • przełączanie kontekstu musi być tanie

  • I / O może blokować każdy wątek w nim zaangażowany, ale nie żaden inny wątek, a na pewno nie wszystkie inne wątki, co miało miejsce w niektórych wczesnych implementacjach.

Często zastanawiałem się, dlaczego wielowątkowość jest tak trudna w Javie, ale teraz staje się jaśniejsza - ostatecznie miało to związek z przejściem na wątki rodzime, które są:

  • dobry w użyciu wszystkich rdzeni procesora

  • dobry w byciu naprawdę współbieżnym, zapewniając niezależne wejścia / wyjścia itp

  • powolne przełączanie kontekstu (w porównaniu z najlepszymi implementacjami zielonego wątku)

  • okropnie chciwy pamięci, ograniczając w ten sposób maksymalną ich użyteczną liczbę

  • słaba abstrakcja jakiejkolwiek podstawy wyrażania świata rzeczywistego, co oczywiście jest wysoce zbieżne.

W dzisiejszych czasach dużo czasu programisty zajmuje kodowanie nieblokujących wejść / wyjść, kontraktów terminowych itp. Szkoda, że ​​nie mamy lepszego poziomu abstrakcji.

Dla porównania, oprócz Erlanga, nowy język Go ma dobrą robotę z ogromną współbieżnością. Dziadek ze wszystkich pozostaje Occam , wciąż trwającym projektem badawczym.

Rick-777
źródło
jak daleko zaszliśmy od czasu, kiedy napisałeś: O
Dmitry
3
Niestety, Rust to kolejny język, który porzucił lepsze abstrakcje współbieżności. Oni także postanowili przejść od wątków kooperacyjnych do wątków rodzimych.
Rick-777,
2
@ Rick-777 Rust jest zbyt niski, aby to zrobić.
Malcolm
15

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.

Sugerowana przez ciebie alternatywa, pula procesów, ma pewne zalety i wady. Największą zaletą, izolacją „wątków”, tak naprawdę niewiele by cię tu sprowadzało. Wielka wada, ekstremalna trudność implementacji i mniej wydajna synchronizacja są tutaj zabójcą transakcji.

Zgadzam się jednak, że istnieją pewne aplikacje (nie Java), w których pula procesów, których można by użyć, jak pula wątków (ale z większą izolacją) byłaby świetna. Wątki dzielą się prawie wszystkim. Dzięki procesom możesz konkretnie wybrać, co chcesz udostępnić. Według mojej wiedzy nikt jeszcze nie podjął wysiłku, aby go wdrożyć.

David Schwartz
źródło
Occam twierdzi, że oferuje to. Był to znaczący język w latach 80., ale cierpiał z powodu braku funduszy na rozwój i dlatego stał się jedynie niszą badawczą. Ale jego pomysły dotyczące współbieżności są teraz tak solidne, jak były wtedy i należy je jeszcze ulepszyć.
Rick-777,
Jeśli jesteś „wielowątkowy” a la golang (szeregowanie typu „M: N”), to teoretycznie tylko jeden zielony wątek jest blokowany przez błąd strony, ponieważ wydaje się, że inne wątki mogą „nabrać luzu” (inne zielone wątki). .. softwareengineering.stackexchange.com/questions/222642/…
rogerdpack
13

Przeciętny kod Java nie przyniesie żadnych korzyści. Java to nie Erlang, a programiści Java nie są tak samo nastawieni jak programiści Erlang. Tego języka nigdy nie zamierzano używać w ten sposób.

Jeśli chcesz prawdziwie lekkich procesów - skorzystaj z Erlanga i stwórz tysiące wątków komunikujących się za pośrednictwem wiadomości. W Javie masz tuzin wątków współużytkujących wspólną pamięć z muteksami i semaforami. To po prostu inny model programowania, zaprojektowany dla innego zestawu problemów.

Logika SK
źródło
Tak więc, aby wyjaśnić, jest to użyteczne podejście w Erlang. I ignorując problemy związane z mentalnością Java, może to rzeczywiście pomóc?
redjamjar
1
@redjamjar, jest mało prawdopodobne, aby był użyteczny w Javie, sam język nie nadaje się do takiego użycia, a jego główna (i jedyna) zaleta - ogromna ilość gotowych bibliotek - nie pasuje dobrze do takiego obcego podejście programistyczne.
SK-logic,
Tak, jeśli chcesz ten model, po prostu użyj Erlanga, będzie o rząd wielkości łatwiejszy
Zachary K
1
Java! = JVM, tylko mówię :)
Kamil Tomšík
1
@Bane, te „zalety” istnieją tylko wtedy, gdy nie masz nic do porównania
SK-logic