Koroutine

Koroutinen sind Computerprogramm-Bestandteile, die Unterprogramme verallgemeinern, um vielfache Zugang-Punkte zu erlauben, um Ausführung an bestimmten Positionen aufzuheben und fortzusetzen. Koroutinen sind gut passend, um vertrautere Programm-Bestandteile wie kooperative Aufgaben, iterators, unendliche Listen und Pfeifen durchzuführen.

Der Begriff "Koroutine" wurde von Melvin Conway in einer 1963-Zeitung hervorgebracht.

Vergleich mit Unterprogrammen

"Unterprogramme sind spezielle Fälle von... Koroutinen." — Donald Knuth. Wenn Unterprogramme angerufen werden, beginnt Ausführung am Anfang, und sobald ein Unterprogramm abgeht, wird es beendet; ein Beispiel eines Unterprogramms kehrt nur einmal zurück. Koroutinen sind außer ähnlich ihnen können auch abgehen, indem sie dazu tragen, oder anderen, Koroutinen nennen, der ihnen erlaubt, an diesem Punkt wieder wiedereingegangen zu werden; aus dem Gesichtspunkt der Koroutine geht es überhaupt nicht ab, aber nennt einfach eine andere Koroutine.

Jedes Unterprogramm kann als eine Koroutine das durchgeführt werden einfach es hat die tragende Eigenschaft von Koroutinen nicht verwendet.

Um eine Programmiersprache mit Unterprogrammen durchzuführen, ist nur ein einzelne Stapel, der am Anfang der Programm-Ausführung vorzugeteilt werden kann, erforderlich. Im Gegensatz werden Koroutinen, fähig, andere Koroutinen als Gleiche aufzufordern, am besten mit Verlängerungen durchgeführt. Verlängerungen können Zuteilung von zusätzlichen Stapeln verlangen und werden deshalb auf Müll-gesammelten höheren Programmiersprachen allgemeiner durchgeführt. Koroutine-Entwicklung kann preiswert durch das Vorzuteilen von Stapeln oder das Verstecken von vorher zugeteilten Stapeln getan werden.

Hier ist ein einfaches Beispiel dessen, wie Koroutinen nützlich sein können. Nehmen Sie an, dass Sie eine Verbraucher-Erzeugerbeziehung haben, wo eine Routine Sachen schafft und sie zu einer Warteschlange hinzufügt und ein anderer Sachen von der Warteschlange entfernt und sie verwendet. Aus Gründen der Leistungsfähigkeit wollen Sie hinzufügen und mehrere Sachen sofort entfernen. Der Code könnte wie das aussehen:

var q: = neue Warteschlange

Koroutine erzeugt

Schleife

während q nicht voller ist

schaffen Sie einige neue Sachen

fügen Sie die Sachen zu q hinzu

Ertrag, um zu verbrauchen

Koroutine verbraucht

Schleife

während q nicht leerer ist

entfernen Sie einige Sachen von q

verwenden Sie die Sachen

Ertrag, um zu erzeugen

Die Warteschlange wird dann völlig gefüllt oder vor der tragenden Kontrolle zur anderen Koroutine mit dem Ertrag-Befehl entleert. Die weiteren Koroutine-Anrufe fangen direkt nach dem Ertrag in der Außenkoroutine-Schleife an.

Obwohl dieses Beispiel häufig verwendet wird, um Nebenläufigkeit einzuführen, ist es nicht notwendig, zwei Fäden zu haben, um das zu erreichen: Die Ertrag-Behauptung kann durch einen Zweig direkt von einer Routine in den anderen durchgeführt werden.

Koroutinen und Generatoren

Generatoren sind auch eine Verallgemeinerung von Unterprogrammen, aber mit auf den ersten Blick der weniger ausdrucksvollen Macht als Koroutinen; da Generatoren in erster Linie verwendet werden, um das Schreiben von iterators zu vereinfachen, gibt die Behauptung in einem Generator keine Koroutine an, um dazu zu springen, aber passiert eher einen Wert zurück zu einer Elternteilroutine. Jedoch ist es noch möglich, Koroutinen oben auf einer Generator-Möglichkeit mithilfe von einer Fahrdienstleiter-Routine auf höchster Ebene durchzuführen (ein Trampolin, im Wesentlichen), der geht, ist Kontrolle ausführlich zu durch Jetons identifizierten Kindergeneratoren zurück von den Generatoren gegangen:

var q: = neue Warteschlange

Generator erzeugt

Schleife während q nicht voller ist schaffen Sie einige neue Sachen fügen Sie die Sachen zu q hinzu

Ertrag verbraucht

Generator verbraucht

Schleife während q nicht leerer ist entfernen Sie einige Sachen von q verwenden Sie die Sachen

Ertrag erzeugt

Unterprogramm-Fahrdienstleiter

var d: = neues Wörterbuch (Generator  iterator)

d [erzeugen]: = Anfang erzeugen

d [verzehren sich]: = Anfang verbrauchen

Var-Strom: = erzeugen

Schleife

Strom: = folgender d [Strom]

Mehrere Durchführungen von Koroutinen für Sprachen mit der Generator-Unterstützung, aber keinen heimischen Koroutinen (z.B Pythonschlange vor 2.5) verwenden das oder ein ähnliches Modell.

Allgemeiner Gebrauch von Koroutinen

Koroutinen sind nützlich, um den folgenden durchzuführen:

  • Staatsmaschinen innerhalb eines einzelnen Unterprogramms, wo der Staat durch den aktuellen Punkt des Zugangs/Ausgangs des Verfahrens bestimmt wird; das kann auf lesbareren Code hinauslaufen.
  • Schauspieler-Modell der Parallelität, zum Beispiel in Videospielen. Jeder Schauspieler hat seine eigenen Verfahren (das trennt wieder logisch den Code), aber sie geben freiwillig Kontrolle zum Hauptplaner auf, der sie folgend durchführt (das ist eine Form des Konsumvereins stark mehrbeanspruchend).
  • Generatoren, und sind diese für den Eingang/Produktion und für das allgemeine Traversal von Datenstrukturen nützlich.

Programmiersprachen, die Koroutinen unterstützen

C# F#

Da Verlängerungen verwendet werden können, um Koroutinen durchzuführen, können Programmiersprachen, die sie unterstützen, auch Koroutinen ganz leicht unterstützen.

Koroutine-Alternativen und Durchführungen

Koroutinen sind als eine mit dem Zusammenbau sprachige Technik entstanden, aber werden auf einigen höheren Programmiersprachen unterstützt. Simula und Modula-2 sind zwei frühe Beispiele von Sprachen, die Koroutinen unterstützen, Lua und Go sind zwei neue Beispiele.

, viele der populärsten Programmiersprachen, einschließlich C und seiner Ableitungen, haben direkte Unterstützung für Koroutinen innerhalb der Sprache oder ihrer Standardbibliotheken nicht. (Das, ist im großen Teil, wegen der Beschränkungen der Stapel-basierten Unterprogramm-Durchführung).

In Situationen, wo eine Koroutine die natürliche Durchführung eines Mechanismus sein würde, aber nicht verfügbar ist, soll die typische Antwort ein Unterprogramm schaffen, das ad hoc Zusammenbau von boolean Fahnen und anderen Zustandsgrößen verwendet, um einen inneren Staat zwischen Anrufen aufrechtzuerhalten. Conditionals innerhalb des Codes laufen auf die Ausführung von verschiedenen Codepfaden auf aufeinander folgenden Anrufen hinaus, die auf den Werten der Zustandsgrößen gestützt sind. Eine andere typische Antwort soll eine ausführliche Zustandmaschine in der Form einer großen und komplizierten Schalter-Behauptung durchführen. Solche Durchführungen sind schwierig, zu verstehen und aufrechtzuerhalten.

Fäden (und in einem kleineren Ausmaß Fasern) sind eine Alternative zu Koroutinen in Hauptströmungsprogrammierumgebungen heute. Fäden stellen Möglichkeiten zur Verfügung, für die kooperative Echtzeitwechselwirkung zu führen, "gleichzeitig" Stücke des Codes durchzuführen. Fäden sind in Umgebungen weit verfügbar, die C unterstützen (und heimisch in vielen anderen neueren Sprachen unterstützt werden), sind für viele Programmierer vertraut, und werden gewöhnlich gut durchgeführt, gut dokumentiert und gut unterstützt. Jedoch, da sie ein großes und schwieriges Problem beheben, schließen sie viele starke und komplizierte Möglichkeiten ein und haben eine entsprechend schwierige Lernkurve. Als solcher wenn eine Koroutine alles ist, was mit einem Faden erforderlich ist, kann Übermaß sein.

Ein wichtiger Unterschied zwischen Fäden und Koroutinen ist, dass Fäden normalerweise Vorkaufs-auf dem Plan stehen, während Koroutinen nicht sind. Weil Fäden in jedem Moment wiedervorgesehen sein können und gleichzeitig durchführen können, müssen Programme mit Fäden über die Blockierung sorgfältig sein. Im Gegensatz, weil Koroutinen nur an spezifischen Punkten im Programm wiedervorgesehen sein können und gleichzeitig nicht durchführen, können Programme mit Koroutinen häufig vermeiden, sich völlig schließen zu lassen. (Dieses Eigentum wird auch als ein Vorteil der Ereignis-gesteuerten oder asynchronen Programmierung zitiert.)

Da Fasern kooperativ auf dem Plan stehen, stellen sie eine ideale Basis zur Verfügung, um Koroutinen oben durchzuführen. Jedoch fehlt die Systembetreuung für Fasern häufig im Vergleich dazu an Fäden.

Durchführung im.NET Fachwerk als Fasern

Während der Entwicklung des.NET Fachwerks 2.0 hat Microsoft das Design des CLR erweitert, der APIs veranstaltet, um Faser-basierte Terminplanung mit einem Auge zu seinem Gebrauch in der Faser-Weise für den SQL Server zu behandeln. Vor der Ausgabe hakt die Unterstützung für die Aufgabenumschaltung ICLRTask an:: SwitchOut wurde wegen zeitlicher Einschränkungen entfernt.

Folglich ist der Gebrauch der Faser-API, um Aufgaben zu schalten, zurzeit nicht eine lebensfähige Auswahl im.NET Fachwerk.

Durchführung im mono abspielbaren

Der Mono abspielbare CLR hat Unterstützung für Verlängerungen, von denen Koroutinen gebaut werden können.

Durchführungen für Java

Es gibt mehrere Durchführungen für Koroutinen in Java trotz der Schwierigkeit, die durch die Abstraktionen innerhalb der javanischen Sprache auferlegt ist, der JVM schließt die Möglichkeit nicht aus. Es gibt vier allgemeine verwendete Methoden.

  • Modifizierter JVMs. Es ist möglich, einen geflickten JVM zu bauen, um Koroutinen mehr heimisch zu unterstützen. Der Da Vinci JVM hat geschaffene Flecke gehabt.
  • Modifizierter Bytecode. Koroutine-Funktionalität ist durch das Neuschreiben des regelmäßigen Javas bytecode entweder im Fluge oder während der Übersetzung möglich. Ein javanisches Koroutine-Projekt.
  • Mit der Plattform spezifische JNI Mechanismen. Diese verwenden JNI Methoden, die im OS oder den C Bibliotheken durchgeführt sind, um die Funktionalität dem JVM zur Verfügung zu stellen.
  • Faden-Abstraktionen. Koroutine-Bibliotheken, die mit Fäden durchgeführt werden, können Schwergewicht sein, obwohl sich Leistung gestützt auf der Faden-Durchführung des JVM ändern wird.

Durchführungen für C

Mehrere Versuche sind mit unterschiedlichen Graden des Erfolgs gemacht worden, Koroutinen in C mit Kombinationen von Unterprogrammen und Makros durchzuführen. Der Beitrag von Simon Tatham ist ein gutes Beispiel des Genres, und seine eigenen Anmerkungen stellen eine gute Einschätzung der Beschränkungen dieser Annäherung zur Verfügung. Der Gebrauch solch eines Geräts kann aufrichtig den writability, die Lesbarkeit und die Haltbarkeit eines Stückes des Codes verbessern, aber wird sich wahrscheinlich umstritten erweisen. In den Wörtern von Tatham: "Natürlich verletzt dieser Trick jeden Codierstandard im Buch... [aber] jeder Codierstandard, der auf syntaktischer Klarheit auf Kosten der algorithmischen Klarheit beharrt, sollte umgeschrieben werden. Wenn Ihr Arbeitgeber Sie entlässt, um diesen Trick zu verwenden, sagen Sie ihnen, dass wiederholt weil der Sicherheitspersonal Sie aus dem Gebäude schleppt."

Eine zuverlässigere Annäherung an das Einführen von Koroutinen in C soll auf der absoluten Beweglichkeit aufgeben und Verarbeiter-Familie spezifische Durchführungen im Zusammenbau von Funktionen schreiben, einen Koroutine-Zusammenhang zu sparen und wieder herzustellen. Der Standard C Bibliothek schließt genannten setjmp von Funktionen und longjmp ein, der verwendet werden kann, um eine Form der Koroutine durchzuführen. Leider, weil Harbison und Zeichen von Steele, "sind der setjmp und die Longjmp-Funktionen notorisch schwierig, und der Programmierer durchzuführen, gesund sein würden, minimale Annahmen über sie zu machen." Was das bedeutet, ist, wenn Harbison und viele Verwarnungen von Steele und Verwahrungen nicht sorgfältig beachtet werden, kann der Gebrauch von setjmp und longjmp, die scheinen, in einer Umgebung zu arbeiten, nicht in einem anderen arbeiten. Schlechter noch sind fehlerhafte Durchführungen dieser Routinen nicht selten. Tatsächlich, setjmp/longjmp, weil es nur einen einzelnen Stapel ermuntert, kann nicht verwendet werden, um natürliche Koroutinen durchzuführen, weil auf dem Stapel gelegene Variablen überschrieben werden, weil eine andere Koroutine denselben Stapel-Raum verwendet.

So für Stapel-basierte Koroutinen in C sind Funktionen erforderlich, um zu schaffen und zwischen abwechselnden Stapeln zu springen. Eine dritte Funktion, die gewöhnlich in maschinenspezifischem C geschrieben werden kann, ist erforderlich, um den Zusammenhang für eine neue Koroutine zu schaffen. C Bibliotheken, die sich zu POSIX oder der Einzelnen Unix Spezifizierung anpassen, stellen solche Routinen wie getcontext, setcontext, makecontext und swapcontext zur Verfügung. Die setcontext Familie von Funktionen ist so beträchtlich mächtiger als setjmp/longjmp, aber übereinstimmende Durchführungen sind so selten wenn nicht seltener. Der Hauptfehler dieser Annäherung ist, dass der Stapel der Koroutine eine feste Größe ist und während der Ausführung nicht angebaut werden kann. So neigen Programme dazu, viel mehr Stapel zuzuteilen, als sie wirklich brauchen, um das Potenzial für die Stapel-Überschwemmung zu vermeiden.

Wegen der Beschränkungen von Standardbibliotheken haben einige Autoren ihren eigenen Bibliotheken für Koroutinen geschrieben. Die libtask Bibliothek von Russ Cox ist ein gutes Beispiel dieses Genres. Es verwendet die Zusammenhang-Funktionen, wenn sie von der geborenen C Bibliothek zur Verfügung gestellt werden; sonst stellt es seine eigenen Durchführungen für ARM, PowerPC, Sparc und x86 zur Verfügung. Andere bemerkenswerte Durchführungen schließen libpcl, coro, lthread, libCoroutine, libconcurrency und libcoro ein.

Durchführungen für C ++

  • Zunahme. Koroutine - Giovanni P. Deretta hat geschaffen, während Google sein "Sommer des Codes 2006" diese tragbare Koroutine-Bibliothek plant, die sich schwer auf die Zunahme und C ++ Schablonen verlässt. Die Zunahme. Koroutine-Dokumentation wird auf einer Nichtzunahme-Seite veranstaltet, weil die Bibliothek unfertig ist und nicht ein Teil der offiziellen Zunahme-Ausgabe.
  • Mordor - 2010, Mozy öffnen sourced ein C ++ Bibliothek, die Koroutinen, mit einer Betonung auf dem Verwenden von ihnen durchführt, um Asynchrone Eingabe/Ausgabe in ein vertrauteres folgendes Modell zu abstrahieren.

Durchführungen für C#

  • Traum von MindTouch - Das Traum-REST-Fachwerk von MindTouch stellt eine Durchführung von Koroutinen zur Verfügung, die auf C# 2.0 iterator Muster gestützt sind
  • Das Schirm-Muster-Fachwerk Caliburn - The Caliburn für WPF verwendet C# 2.0 iterators, um UI-Programmierung besonders in asynchronen Drehbüchern zu erleichtern.
  • Macht-Einfädeln-Bibliothek - Die Macht-Einfädeln-Bibliothek durch Jeffrey Richter führt AsyncEnumerator durch, der vereinfachtem Asynchronem Programmiermodell das Verwenden von mit Sitz in iterator Koroutinen zur Verfügung stellt.
  • Servelat Stücke - Das Servelat Stück-Projekt von Yevhen Bobrov stellt durchsichtigen asynchrony für Silverlight WCF Dienstleistungen und Fähigkeit zur Verfügung, jede gleichzeitige Methode asynchron zu nennen. Die Durchführung basiert auf den Koroutinen von Caliburn iterator und C# iterator Blöcke.
  • http://msdn.microsoft.com/en-us/library/dscyy5s0 (Gegen 80).aspx - Der.NET 2.0 + stellt Fachwerk jetzt Koroutine-Funktionalität durch das iterator Muster und Ertrag-Schlüsselwort zur Verfügung.

Durchführungen für die Pythonschlange

Durchführungen für den Rubin

Durchführungen für Perl

Koroutinen werden auch ein Teil von Perl 6 sein.

Durchführungen für den Plausch

Seitdem, in den meisten Plausch-Umgebungen, ist der Ausführungsstapel ein erstklassiger Bürger, Koroutinen können ohne zusätzliche Bibliothek oder VM-Unterstützung durchgeführt werden.

Durchführungen für das Schema

Da Schema volle Unterstützung für Verlängerungen zur Verfügung stellt, ist die Durchführung von Koroutinen fast trivial, nur dass eine Warteschlange von Verlängerungen verlangend, aufrechterhalten werden.

Durchführungen für Delphi

Durchführungen auf Zusammenbau-Sprachen

Maschinenabhängige Zusammenbau-Sprachen stellen häufig direkte Methoden für die Koroutine-Ausführung zur Verfügung. Zum Beispiel, in makro11, die Zusammenbau-Sprache der PDP-11 Familie von Minicomputern, wird der "klassische" Koroutine-Schalter durch die Instruktion "JSR PC,@ (SP) +" bewirkt (der sich als Oktal-"004736" versammelt), der zur Adresse springt, die vom Stapel knallen gelassen ist, und den Strom (d. h. dieser der folgenden) Instruktionsadresse auf den Stapel stößt. Auf VAXen (in makro32) ist die vergleichbare Instruktion "JSB (SP) +" (der sich als Hexe "9E 16" versammelt, weil der Monteur es (mit tatsächlich Bytes umgekehrt) zeigt. Sogar auf Motorola 6809 gibt es die Instruktion "JSR [S ++]", der sich als (Hexe) "n.Chr. F1" versammelt; bemerken Sie "++", weil 2 Bytes (der Adresse) vom Stapel knallen gelassen werden. Diese Instruktion wird sehr im (normalen) 'Monitor' verwendet Helfen 09.

Einfach das Wegrufen der Routine, deren Adresse auf der Spitze des Stapels ist, erschöpft natürlich die Möglichkeiten auf der Zusammenbau-Sprache (N) nicht!

Siehe auch

  • Pfeifen von Unix - eine Art Koroutine, die verwendet ist, um zwischen Programmen zu kommunizieren

Weiterführende Literatur

Links


Fred Gallagher (Karikaturist) / Hund-Stern
Impressum & Datenschutz