Jakie są przypadki użycia koroutine?

Koncepcja coroutine brzmi bardzo interesująco, ale nie wiem, czy ma sens w prawdziwym produktywnym środowisku? Jakie są przypadki użycia korutyn, które można rozwiązać bardziej elegancko, prościej lub wydajniej, jak w przypadku innych metod?

Author: Mnementh, 2008-11-20

7 answers

True coroutines wymagają wsparcia z twoich narzędzi - muszą być zaimplementowane przez kompilator i obsługiwane przez bazowy framework.

Jeden rzeczywisty przykład Coroutines znajduje się za pomocą słowa kluczowego "yield return"dostarczonego w C# 2.0, które pozwala na napisanie metody, która zwraca wiele wartości dla pętli.

"yield return" ma jednak ograniczenia - implementacja używa klasy pomocniczej do przechwytywania stanu i obsługuje tylko określony przypadek coroutine jako generator (iterator).

W bardziej ogólnym przypadku zaletą Coroutines jest to, że sprawiają one, że pewne obliczenia oparte na stanie są znacznie łatwiejsze do wyrażenia i łatwiejsze do zrozumienia - implementacja maszyny stanowej jako zbioru coroutines może być bardziej elegancka niż bardziej popularne podejścia. Wymaga to jednak wsparcia i narzędzi, które jeszcze nie istnieją w C# lub Javie.

 18
Author: Bevan,
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
2008-11-19 23:23:57

Kilka dobrych odpowiedzi opisujących czym są koroutiny.

Ale dla rzeczywistego przypadku użycia. Weź serwer WWW. Ma wiele jednoczesnych połączeń i chce zaplanować odczyt i zapis wszystkich z nich.

Można to zaimplementować za pomocą coroutines. Każde połączenie jest coroutine, który odczytuje / zapisuje niewielką ilość danych, a następnie "oddaje" kontrolę do schedulera, który przechodzi do następnego coroutine (który robi to samo), gdy przechodzimy przez wszystkie dostępne znajomości.

 44
Author: Ali Afshar,
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
2008-11-20 00:00:42

Wiele z nich, na przykład:

grep TODO *.c *.h | wc -l

Powyższy rurociąg jest dokładnie koroutine: grep polecenie generuje sekwencję linii, które trafiają do bufora, wc polecenie "zjada je"; jeśli bufor się wypełni, grep "blokuje" aż bufor się opróżni, a jeśli bufor jest pusty, wc Komenda czeka na nowe wejście.

Rzecz w coroutinach jest taka, że są one obecnie najczęściej używane albo w bardziej ograniczonych wzorach, jak wspomniane Generatory Pythona, albo jako rurociągi.

Jeśli chcesz spojrzeć na nie więcej, Zobacz artykuły Wikipedii, zwłaszcza na coroutines i Iteratory .

 19
Author: Charlie Martin,
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
2008-11-20 03:26:43

Wiem, że minęło prawie 5 lat od zadanego pytania, ale dziwię się, że nikt nie wspomniał o przypadku użycia gier, w których koroutiny są często używane do obliczenia czasu.

Aby utrzymać stałą częstotliwość klatek w grze, powiedzmy 60 fps, masz około 16.6 ms Na wykonanie kodu w każdej klatce. Obejmuje to symulację fizyki, przetwarzanie danych wejściowych, rysowanie/malowanie.

Powiedzmy, że twoja metoda jest wykonywana w każdej klatce. Jeśli twoja metoda trwa długo i kończy się w przypadku wielu klatek, reszta obliczeń zostanie zachwiana w pętli gry, co spowoduje, że użytkownik zobaczy "jank" (nagły spadek liczby klatek na sekundę).

To, co pozwala Ci wykonać, to jakoś czas pokroić te obliczenia tak, aby przebiegały po trochu w każdej klatce.

Aby tak się stało, coroutines zasadniczo pozwala metodzie" oddać "obliczenia z powrotem do "wywołującego" (w tym przypadku pętli gry) tak, że następnym razem, gdy metoda zostanie wywołana, wznawia się od tam, gdzie to się skończyło.

 18
Author: numan salati,
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
2018-07-19 04:23:06

Koroutiny są przydatne do implementacji wzorców producent / konsument.

Na przykład, Python wprowadził coroutiny w funkcji języka o nazwie Generatory , która miała na celu uproszczenie implementacji iteratorów.

Mogą być również przydatne do implementacji wielozadaniowości kooperacyjnej, gdzie każde zadanie jest koroutinem, który daje się schedulerowi / reaktorowi.

 11
Author: ddaa,
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
2008-11-19 23:31:14

Coroutines mogą być przydatne, gdy system ma dwa lub więcej fragmentów kodu, których najbardziej naturalna reprezentacja byłaby sekwencyjną serią kroków, która wymaga dużo czekania.

Na przykład, rozważmy urządzenie, które ma interfejs użytkownika LCD-i-klawiatura i modem, i musi używać modemu okresowo wywoływać i raportować swój stan niezależnie od tego, co użytkownik na klawiaturze robi. Najprzyjemniejszym sposobem napisania interfejsu użytkownika może być użycie takich funkcji jak "input_numeric_value (&CONV_SPEED_FORMAT, & conveyor_speed);", które zwróci, gdy użytkownik wprowadzi wartość, a najładniejszym sposobem obsługi komunikacji może być użycie funkcji takich jak " wait_for_carrier ();", które zwróci, gdy jednostka połączy się lub stwierdzi, że nie będzie.

Bez corutyn, albo podsystem UI, albo podsystem modemu musiałby być zaimplementowany przy użyciu maszyny stanowej. Zastosowanie koroutinów umożliwia zapisanie obu podsystemów w najbardziej naturalny styl. Zauważ, że ważne jest, aby żaden podsystem nigdy nie przechodził bardzo długo bez wprowadzenia rzeczy w stan "spójny" i wywołania yield(), ani też nie wywołał yield () bez wprowadzenia rzeczy w stan "spójny", ale zazwyczaj nie jest trudno spełnić te ograniczenia.

Zauważ, że chociaż można użyć pełnowymiarowej wielozadaniowości, to wymaga to użycia blokad w każdym miejscu, gdy wspólny stan zostanie zmieniony. Ponieważ przełącznik koroutine nigdy nie zmieni rzeczy, z wyjątkiem podczas wywołania yield (), każda z funkcji może dowolnie zmieniać stan współdzielony tak długo, jak zapewnia, że wszystko jest w porządku przed następnym yield () i jest przygotowana na to, że druga funkcja zmieni stan "podczas" yield ().

 9
Author: supercat,
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
2010-07-14 15:52:35

Jako bardziej konkretny przykład w linii producent / konsument, coś tak prostego, jak skromny program raportowania partii może faktycznie używać procedur kooperacyjnych.

Kluczową wskazówką dla tego przykładu jest posiadanie nietrywialnej pracy, która zużywa dane wejściowe (np. parsowanie danych lub gromadzenie opłat i płatności na koncie), oraz nietrywialnej pracy, aby wytworzyć wyjście. Gdy masz te cechy:

  • łatwo jest uporządkować / zrozumieć kod po stronie wejścia, jeśli można "emitować" jednostki praca w różnych miejscach.
  • równie łatwo jest uporządkować / zrozumieć kod po stronie wyjściowej, jeśli może "chwycić" następną jednostkę pracy w zagnieżdżonej strukturze sterowania.

Zatem korutyny i kolejki są przyjemnymi technikami, które można mieć do dyspozycji.

 6
Author: joel.neely,
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-02-04 18:20:32