Różnica między "coroutine" a "thread"?

Jakie są różnice między "koroutinem" a "nicią"?

Author: jldupont, 2009-12-20

5 answers

Koroutiny są formą sekwencyjnego przetwarzania: tylko jedna jest wykonywana w danym momencie (podobnie jak podprogramy AKA procedury AKA funkcje-po prostu przekazują pałeczkę między sobą bardziej płynnie).

Wątki są (przynajmniej koncepcyjnie) formą przetwarzania współbieżnego: wiele wątków może być wykonywanych w danym momencie. (Tradycyjnie na jednordzeniowych, jednordzeniowych maszynach, współbieżność była symulowana z pewną pomocą systemu operacyjnego-obecnie, ponieważ tak wiele maszyn jest wielordzeniowe i/lub wielordzeniowe, wątki będą de facto wykonywane jednocześnie, a nie tylko "koncepcyjnie").

 62
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-15 19:24:49

Pierwsze czytanie: współbieżność a równoległość - jaka jest różnica?

Współbieżność to rozdzielenie zadań w celu zapewnienia przeplatania egzekucja. Równoległość to jednoczesne wykonywanie wielu elementy pracy w celu zwiększenia prędkości. - https://github.com/servo/servo/wiki/Design

Krótka odpowiedź: w przypadku wątków system operacyjny przełącza uruchamiane wątki prewencyjnie zgodnie ze swoim harmonogramem, który jest algorytm w jądrze systemu operacyjnego. W koroutinach programista i język programowania określają, kiedy przełączać koroutiny; innymi słowy, zadania są wspólnie wielozadaniowe poprzez wstrzymywanie i wznawianie funkcji w punktach zadanych, zazwyczaj (ale niekoniecznie) w ramach jednego wątku.

Długa odpowiedź: w przeciwieństwie do wątków, które są wstępnie zaplanowane przez system operacyjny, przełączniki coroutine są kooperacyjne, czyli programista (i ewentualnie programowanie język i jego runtime) kontroluje, kiedy nastąpi przełącznik.

W przeciwieństwie do gwintów, które są prewencyjne, przełączniki koronowe są kooperatywny (programista kontroluje, kiedy nastąpi przełącznik). Na kernel nie bierze udziału w przełącznikach coroutine. - http://www.boost.org/doc/libs/1_55_0/libs/coroutine/doc/html/coroutine/overview.html

Język obsługujący natywne wątki może wykonywać swoje wątki (wątki użytkownika) na wątki systemu ( wątki jądra). Każdy proces ma co najmniej jeden wątek jądra. Wątki jądra są podobne do procesów, z tym wyjątkiem, że dzielą przestrzeń pamięci w swoim procesie z wszystkimi innymi wątkami w tym procesie. Proces "posiada" wszystkie przypisane zasoby, takie jak pamięć, uchwyty plików, gniazda, uchwyty urządzeń itp., a wszystkie te zasoby są współdzielone pomiędzy wątki jądra.

Scheduler systemu operacyjnego jest częścią jądra, które uruchamia każdy wątek przez pewną ilość czasu (na jednej maszynie procesorowej). Scheduler przydziela czas (timeslicing) do każdego wątku, a jeśli wątek nie zostanie ukończony w tym czasie, scheduler go opróżnia (przerywa i przełącza się do innego wątku). Wiele wątków może działać równolegle na maszynie wieloprocesorowej, ponieważ każdy wątek może być (ale nie musi być) zaplanowany na oddzielnym procesorze.

Na pojedynczym komputerze procesorowym wątki są synchronizowane w czasie i prewencyjne (przełączane pomiędzy) szybko (włączone Linux domyślnym czasem jest 100ms), co czyni je współbieżnymi. Jednak nie mogą być uruchamiane równolegle (jednocześnie), ponieważ jednordzeniowy procesor może uruchamiać tylko jedną rzecz na raz.

Koroutiny i / lub generatory mogą być używane do implementacji funkcji kooperacyjnych. Zamiast być uruchamiane na wątkach jądra i zaplanowane przez system operacyjny, działają w jednym wątku, dopóki nie ulegną lub nie zakończą, ulegając innym funkcjom określonym przez programistę. Języki z generatorami , takie jak Python i ECMAScript 6, mogą być używane do budowania coroutines. Async / wait (widziane w C#, Python, ECMAscript 7, Rust) jest abstrakcją zbudowaną na bazie funkcji generatora, które dają kontrakty futures/promises.

W niektórych kontekstach, coroutines mogą odnosić się do funkcji stosowych, podczas gdy Generatory mogą odnosić się do funkcji bez stosów.

Włókna, lekkie wątki i Zielone wątki to Inne nazwy dla coroutines lub coroutine-like things. Mogą czasami wyglądać (zazwyczaj celowo) bardziej jak wątki systemu operacyjnego w języku programowania, ale nie działają równolegle jak prawdziwe wątki i działają jak coroutines. (Mogą występować bardziej szczegółowe cechy techniczne lub różnice między tymi pojęciami w zależności od języka lub implementacji.)

Na przykład Java miała " Zielone wątki"; były to wątki zaplanowane przez maszynę wirtualną Javy (JVM) zamiast natywnie na wątkach jądra systemu operacyjnego. Nie działały one równolegle ani nie korzystały z wielu procesorów/rdzeni - ponieważ wymagałoby to natywnego wątku! Ponieważ nie były one zaplanowane przez system operacyjny, były bardziej jak coroutines niż wątki jądra. Zielone wątki są tym, czego Java używała do czasu wprowadzenia natywnych wątków do Javy 1.2.

Wątki zużywają zasoby. W JVM każdy wątek ma swój własny stos, Zwykle o rozmiarze 1MB. 64k to najmniej ilość wolnego miejsca w stosie na wątek w JVM. Rozmiar stosu wątków można skonfigurować w wierszu poleceń dla JVM. Pomimo nazwy, wątki nie są wolne, ze względu na ich wykorzystanie zasobów, takich jak każdy wątek potrzebuje własnego stosu, thread-local storage (jeśli istnieje) oraz koszt planowania wątków/przełączania kontekstu / unieważniania pamięci podręcznej CPU. Jest to jeden z powodów, dla których coroutines stały się popularne w zastosowaniach o krytycznym znaczeniu dla wydajności, wysoce współbieżnych.

Mac OS pozwoli tylko na proces przydzielania około 2000 wątków, a Linux przydziela 8MB stosu na wątek i pozwoli tylko tyle wątków, które zmieszczą się w fizycznej pamięci RAM.

W związku z tym wątki są najcięższą wagą (pod względem wykorzystania pamięci i czasu przełączania kontekstu), następnie coroutines, a wreszcie generatory są najlżejsze.

 94
Author: llambda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-01 22:50:25

Około 7 lat późno, ale odpowiedzi tutaj brakuje jakiegoś kontekstu na co-rutyny vs wątki. Dlaczego koroutiny cieszą się ostatnio tak dużą uwagą i kiedy miałbym ich używać w porównaniu do wątków ?

Po pierwsze, jeśli koroutiny działają jednocześnie (nigdy w równolegle), Dlaczego ktoś woli je od wątków?

Odpowiedź jest taka, że coroutines mogą zapewnić Bardzo wysoki poziom współbieżności z bardzo małym obciążeniem . Zazwyczaj w środowisku wątków masz co najwyżej 30-50 wątków, zanim ilość straconego narzutu faktycznie zaplanuje te wątki (przez System scheduler) znacząco zmniejsza ilość czasu, przez który wątki faktycznie wykonują użyteczną pracę.

Ok więc z wątkami można mieć równoległość, ale nie za dużo równoległości, czy to nie jest jeszcze lepsze niż wspólne działanie w jednym wątku? Niekoniecznie. Pamiętaj, że procedura współbieżna może nadal wykonywać współbieżność bez Scheduler overhead-po prostu sam zarządza przełączaniem kontekstu.

Na przykład, jeśli masz rutynę wykonującą jakąś pracę i wykonuje operację, o której wiesz, że zostanie zablokowana przez jakiś czas( np. żądanie sieciowe), za pomocą procedury współbieżnej możesz natychmiast przełączyć się na inną rutynę bez narzutu włączania harmonogramu systemowego do tej decyzji-tak, programista musi określić, kiedy można przełączać się na procedury współbieżne.

Z wieloma rutynami wykonującymi bardzo małe prace i dobrowolnie przełączając się między sobą, osiągnąłeś poziom wydajności, jakiego nie mógłby osiągnąć żaden scheduler. Teraz możesz mieć tysiące koroutines pracujących razem, w przeciwieństwie do dziesiątek wątków.

Ponieważ twoje procedury teraz przełączają się między sobą wstępnie ustalone punkty, możesz teraz również unikać blokowania na współdzielonych strukturach danych (ponieważ nigdy nie powiesz swojemu kodowi, aby przełączył się na inny coroutine w środku krytycznej sekcji)

Inny zaletą jest znacznie mniejsze zużycie pamięci. W przypadku modelu wątkowego każdy wątek musi przydzielić własny stos, więc zużycie pamięci rośnie liniowo wraz z liczbą wątków, które posiadasz. W przypadku procedur współbieżnych liczba wykonywanych procedur nie ma bezpośredniego związku z korzystaniem z pamięci.

I wreszcie, Ko-procedury zwracają dużą uwagę, ponieważ w niektórych językach programowania (takich jak Python) twoje wątki nie mogą działać równolegle - działają jednocześnie podobnie jak coroutines, ale bez niskiej pamięci i wolnego planowania.

 56
Author: Martin Konecny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-16 04:07:58

Jednym słowem: uprzedzenie. Coroutines zachowują się jak żonglerzy, którzy ciągle przekazują sobie dobrze wyćwiczone punkty. Wątki (prawdziwe wątki) mogą być przerywane w prawie każdym punkcie, a następnie wznowione później. Oczywiście wiąże się to z różnego rodzaju konfliktami zasobów, stąd niesławny Gil - Global Interpreter Lock Pythona.

Wiele implementacji wątków jest bardziej podobnych do coroutines.

 12
Author: Peter Rowell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-20 03:11:15

To zależy od języka, którego używasz. Na przykład w Lua są to to samo (zmienna typu koroutine nazywa się thread).

Zwykle jednak coroutines implementują dobrowolne poddanie się, gdzie (ty) programista decyduje, gdzie yield, czyli daje kontrolę innej rutynie.

Zamiast tego wątki są automatycznie zarządzane (zatrzymywane i uruchamiane) przez system operacyjny, a nawet mogą działać w tym samym czasie na procesorach wielordzeniowych.
 7
Author: Andreas Bonini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-20 03:09:09