Was ist eine Coroutine? Wie hängen sie mit der Parallelität zusammen?
terminology
coroutine
yesraaj
quelle
quelle
Antworten:
Coroutinen und Parallelität sind weitgehend orthogonal. Coroutinen sind eine allgemeine Kontrollstruktur, bei der die Flusskontrolle kooperativ zwischen zwei verschiedenen Routinen übertragen wird, ohne zurückzukehren.
Die 'Yield'-Anweisung in Python ist ein gutes Beispiel. Es entsteht eine Coroutine. Wenn die 'Ausbeute' angetroffen wird, wird der aktuelle Status der Funktion gespeichert und die Steuerung an die aufrufende Funktion zurückgegeben. Die aufrufende Funktion kann dann die Ausführung zurück an die Yielding-Funktion übertragen, und ihr Status wird bis zu dem Punkt wiederhergestellt, an dem die 'Yield' festgestellt wurde, und die Ausführung wird fortgesetzt.
quelle
Coroutines are a general control structure whereby flow control is cooperatively passed between two different routines without returning.
<- Dies ist Parallelität. Das Wort, das Sie suchen, ist Parallelität.orthogonal = Not similar to each other
?orthogonal
bedeutet "unabhängig voneinander".Aus der Programmierung in Lua ,
Coroutines
Abschnitt " ":Der Punkt ist also: Coroutinen sind "kollaborativ". Selbst in Mehrkernsystemen wird immer nur eine Coroutine ausgeführt (es können jedoch mehrere Threads parallel ausgeführt werden). Zwischen Coroutinen besteht kein Präemptiv, die laufende Coroutine muss die Ausführung explizit aufgeben.
Für "
concurrency
" können Sie auf Rob Pikes Folie verweisen :Während der Ausführung von Coroutine A wird die Kontrolle an Coroutine B übergeben. Nach einiger Zeit gibt die Coroutine B die Kontrolle an Coroutine A zurück. Da zwischen Coroutinen eine Abhängigkeit besteht und sie zusammen ausgeführt werden müssen, sind die beiden Coroutinen nicht gleichzeitig .
quelle
Ich finde die meisten Antworten zu technisch, obwohl es sich um eine technische Frage handelt. Es fiel mir schwer, den Coroutine-Prozess zu verstehen. Ich verstehe es irgendwie, aber dann verstehe ich es nicht gleichzeitig.
Ich fand diese Antwort hier sehr hilfreich:
https://dev.to/thibmaek/explain-coroutines-like-im-five-2d9
Um aus Idan Arye zu zitieren:
Überprüfen Sie auf jeden Fall den Link, es gibt noch viel mehr, dass ich nicht alles zitieren kann.
quelle
Coroutine ähnelt Subroutine / Threads. Der Unterschied besteht darin, dass ein Aufrufer, sobald er eine Unterroutine / Threads aufgerufen hat, niemals mehr zur Aufruferfunktion zurückkehrt. Eine Coroutine kann jedoch nach dem Ausführen einiger Codeteile zum Aufrufer zurückkehren, sodass der Aufrufer einen Teil seines eigenen Codes ausführen und zum Coroutine-Punkt zurückkehren kann, an dem die Ausführung gestoppt wurde, und von dort aus fortfahren kann. dh. Eine Coroutine hat mehr als einen Ein- und Ausstiegspunkt
quelle
Grundsätzlich gibt es zwei Arten von Coroutinen:
Kotlin implementiert stapellose Coroutinen - es bedeutet, dass die Coroutinen keinen eigenen Stapel haben, sodass sie nicht auf nativen Threads abgebildet werden.
Dies sind die Funktionen zum Starten der Coroutine:
Hier können Sie mehr lernen:
https://www.kotlindevelopment.com/deep-dive-coroutines/
https://blog.mindorks.com/what-are-coroutines-in-kotlin-bf4fecd476e9
quelle
In der Python-
gevent
Bibliothek befindet sich einecoroutine
basierte Netzwerkbibliothek, die Ihnen threadähnliche Funktionen wie asynchrone Netzwerkanforderungen bietet, ohne den Aufwand für das Erstellen und Zerstören von Threads. Die verwendetecoroutine
Bibliothek istgreenlet
.quelle
Von Python Coroutine :
Aus Coroutinen (C ++ 20)
Vergleichen Sie mit der Antwort anderer:
Meiner Meinung nach ist der später wieder aufgenommene Teil ein wesentlicher Unterschied, genau wie bei @ Twinkle.
Obwohl viele Felder des Dokuments noch in Arbeit sind, ähnelt dieser Teil den meisten Antworten, mit Ausnahme von @Nan Xiaos
Da es aus dem Programm in Lua zitiert wird, ist es möglicherweise sprachbezogen (derzeit nicht mit Lua vertraut), nicht alle Dokumente erwähnen den einzigen Teil.
Die Beziehung zur gleichzeitigen:
Es gibt einen "Execution" -Teil der Coroutines (C ++ 20). Zu lange, um hier zu zitieren.
Neben dem Detail gibt es mehrere Zustände.
als Kommentar von @Adam Arold unter der Antwort von @ user217714. Es ist Parallelität.
Aber es unterscheidet sich vom Multithreading. von std :: thread
Da es sich um eine Parallelität handelt, funktioniert es wie Multithreading, insbesondere wenn das Warten unvermeidlich ist (aus Sicht des Betriebssystems). Deshalb ist es auch verwirrend.
quelle
Eine Coroutine ist eine spezielle Art von Unterprogramm. Anstelle der Master-Slave-Beziehung zwischen einem Aufrufer und einem aufgerufenen Unterprogramm, die bei herkömmlichen Unterprogrammen besteht, sind Anrufer und aufgerufene Coroutinen gerechter.
Eine Coroutine ist ein Unterprogramm, das mehrere Einträge enthält und diese selbst steuert - direkt in Lua unterstützt
Auch als symmetrische Steuerung bezeichnet: Anrufer und angerufene Coroutinen sind gleichberechtigter
Ein Coroutine-Anruf wird als Lebenslauf bezeichnet
Die erste Wiederaufnahme einer Coroutine beginnt, aber nachfolgende Aufrufe werden an der Stelle unmittelbar nach der zuletzt ausgeführten Anweisung in der Coroutine eingegeben
Coroutinen nehmen sich wiederholt wieder auf, möglicherweise für immer
Coroutinen ermöglichen die quasi gleichzeitige Ausführung von Programmeinheiten (die Coroutinen); ihre Ausführung ist verschachtelt, aber nicht überlappend
quelle
Ich finde eine Erklärung von diesem Link ist ziemlich einfach. Keine dieser Antworten versucht, Parallelität und Parallelität zu erklären, mit Ausnahme des letzten Aufzählungspunkts in dieser Antwort .
zitiert aus "Programmierung Erlang" von Joe Armstrong, dem legendären:
Ein gleichzeitiges Programm ist ein Programm, das in einer gleichzeitigen Programmiersprache geschrieben ist. Wir schreiben gleichzeitig Programme aus Gründen der Leistung, Skalierbarkeit oder Fehlertoleranz.
Eine gleichzeitige Programmiersprache ist eine Sprache mit expliziten Sprachkonstrukten zum Schreiben gleichzeitiger Programme. Diese Konstrukte sind ein wesentlicher Bestandteil der Programmiersprache und verhalten sich auf allen Betriebssystemen gleich.
Ein Parallelcomputer ist ein Computer mit mehreren Prozessoreinheiten (CPUs oder Kernen), die gleichzeitig ausgeführt werden können.
Parallelität ist also nicht dasselbe wie Parallelität. Sie können weiterhin gleichzeitig Programme auf einem Single-Core-Computer schreiben. Mit dem Time-Sharing-Planer haben Sie das Gefühl, dass Ihr Programm gleichzeitig ausgeführt wird.
Das gleichzeitige Programm kann möglicherweise parallel auf einem parallelen Computer ausgeführt werden, ist jedoch nicht garantiert . Das Betriebssystem bietet Ihnen möglicherweise nur einen Kern zum Ausführen Ihres Programms.
Daher Gleichzeitigkeit ist ein Software - Modell von einem gleichzeitigen Programm , das Ihr Programm nicht bedeuten kann physisch parallel laufen.
ein. erreicht es Parallelität oder Parallelität?
Um es einfach zu machen, lassen Sie es uns auf einem einzigen Kern diskutieren Computer .
Parallelität wird durch Time-Shares vom Betriebssystem erreicht. Ein Thread führt seinen Code in den ihm zugewiesenen Zeitrahmen auf dem CPU-Kern aus. Es kann vom Betriebssystem vorbelegt werden. Es kann auch die Kontrolle über das Betriebssystem ermöglichen.
Eine Coroutine hingegen gibt einer anderen Coroutine innerhalb des Threads die Kontrolle, nicht dem Betriebssystem. Daher nutzen alle Coroutinen innerhalb eines Threads immer noch den Zeitrahmen für diesen Thread, ohne den CPU-Kern anderen vom Betriebssystem verwalteten Threads zu überlassen.
Daher kann man sich vorstellen , dass Coroutine Zeitanteile durch den Benutzer erzielt, nicht durch das Betriebssystem (oder Quasi-Parallelität). Coroutinen werden auf demselben Kern ausgeführt, der dem Thread zugewiesen ist, der diese Koroutinen ausführt.
Erreicht Coroutine Parallelität? Wenn es sich um CPU-gebundenen Code handelt, nein. Wie bei Time-Shares haben Sie das Gefühl, dass sie parallel laufen, ihre Ausführungen jedoch verschachtelt und nicht überlappend sind. Wenn es E / A-gebunden ist, wird es parallel durch Hardware (E / A-Geräte) und nicht durch Ihren Code erreicht.
b. der Unterschied zum Funktionsaufruf?
Wie das Bild zeigt, muss kein Anruf getätigt werden,
return
um die Steuerung zu wechseln. Es kann ohne nachgebenreturn
. Eine Coroutine speichert und teilt den Status im aktuellen Funktionsrahmen (Stapel). Es ist also viel leichter als die Funktion, da Sie keine Register und lokalen Variablen speichern müssen, um den Aufrufstapel zu stapeln und zurückzuspulen, wenncall ret
.quelle
Ich werde die Antwort von @ user21714 erweitern. Coroutinen sind unabhängige Ausführungspfade, die nicht gleichzeitig ausgeführt werden können. Sie hängen von einem Controller - beispielsweise einer
python
Controller-Bibliothek - ab, um das Umschalten zwischen diesen Pfaden zu handhaben. Damit dies funktioniert, müssen die Coroutinen selbstyield
oder ähnliche Strukturen aufrufen , mit denen ihre Ausführung angehalten werden kann.Threads werden stattdessen auf unabhängigen Rechenressourcen und parallel zueinander ausgeführt. Da sie sich auf unterschiedlichen Ressourcen befinden, muss Yield nicht aufgerufen werden , damit die anderen Ausführungspfade fortgesetzt werden können.
Sie können diesen Effekt sehen, indem Sie ein Programm mit mehreren Threads starten - z. B. eine
jvm
Anwendung -, in der alle achtcore i7
Hyperthread-Kerne verwendet werden. Möglicherweise wird inActivity Monitor
oder eine Auslastung von 797% angezeigtTop
. Stattdessen wird beim Ausführen eines typischenpython
Programms - auch eines mitcoroutines
oderpython threading
- die maximale Auslastung bei 100% liegen. Dh ein Maschinen-Hyperthread.quelle