Koroutine
# Koroutine

In der Informatik sind Koroutinen (auch Coroutinen) eine Verallgemeinerung des Konzepts einer Prozedur oder Funktion. Der prinzipielle Unterschied zwischen Koroutinen und Prozeduren ist, dass Koroutinen ihren Ablauf unterbrechen und später wieder aufnehmen können, wobei sie ihren Status beibehalten.
Koroutinen stellen also eine hohe Abstraktionsebene einer Funktion, oder Prozedur dar, die einen Lebenszyklus besitzt. Dadurch ist ein hoher Grad an Parallelisierung möglich. Funktionen oder Prozeduren sind in diesem Fall wörtlich zu nehmen, da eine Koroutine keine Abhängigkeit zu einem externen Zustand haben sollte. Die Funktionsparameter der Koroutine allein müssen vollständig genügen, damit im Funktionskörper die Berechnung korrekt durchlaufen kann.
Unter den ältesten Programmiersprachen, die Koroutinen unterstützen, sind Simula oder Modula-2. Auch moderne Sprachen wie Python kennen ähnliche Konzepte. In einigen weit verbreiteten Sprachen wie C oder Java gestaltet sich die Implementierung jedoch schwierig. Der Begriff selbst stammt von Melvin Conway, der ihn 1963 in einer Veröffentlichung über Compilerbau benutzte. Donald Knuth bezeichnet Prozeduren als Spezialfall von Koroutinen.

## Implementierungen

Koroutinen können generell in Sprachen, die sie nicht direkt unterstützen, simuliert werden. Dabei ist ein sprachunabhängiger Weg, vergleichbares Verhalten zu programmieren, die Benutzung von Threads, die wechselseitig ablaufen und nach Abgabe der Kontrolle abwarten, bis sie die Kontrolle zurückerhalten. Eine andere Möglichkeit, die in jeder Programmiersprache funktioniert, ist das Aufrollen von Koroutinen. Hierbei muss die Koroutine ihren Status selbst vorhalten (beispielsweise in einer globalen Variablen) und dann bei jedem Aufruf an die entsprechende Stelle ihres Codes springen. Da es in vielen Programmiersprachen nicht möglich ist, in die Mitte eines Blocks (beispielsweise in eine Schleife) zu springen, müssen solche Konstrukte in so einem Fall ebenfalls durch Simulationen ersetzt werden.

### Python

Die Programmiersprache Python unterstützt Koroutinen über die asyncio API. Seit Python 3.5 gibt es hierzu die Schlüsselwörter await und async. Eine Koroutine wird mittels async def definiert. await wartet auf die Fertigstellung einer Koroutine und gibt während der Wartezeit die Ausführungskontrolle zurück. Koroutinen können nebenläufig ausgeführt werden und ermöglichen dadurch ein kooperatives Multitasking.
Eine andere Möglichkeit ist die Verwendung von Generatoren als Koroutine. Dabei kann mit dem Schlüsselwort yield der Ablauf einer Funktion vorübergehend unterbrochen werden. Intern wird jedoch bei Aufruf einer solchen Generator-Funktion ein Objekt erzeugt, das den Status vorhält. Realisiert wird dies, indem bei Abgabe der Kontrolle das vollständige Stackframe zwischengespeichert und bei Wiederaufnahme wiederhergestellt wird. Es ist möglich, einem Generator bei der Objektinstanziierung Parameter zu übergeben.
In Python 2.5 wurde die Syntax des yield-Schlüsselworts erweitert, um kooperatives Multitasking zu ermöglichen. In Python 3 folgten Erweiterungen zur Nutzung von Generatoren als Koroutinen, unter anderem durch die Einführung der Schlüsselwörter async und await. In Version 3.11 wurde diese Funktionalität wieder entfernt. Generatoren mit dem Schlüsselwort yield sind weiterhin Teil der Sprache, für die Schlüsselwörter async und await ist jedoch die asyncio API vorgesehen.

### C

C unterstützt weder Koroutinen noch vergleichbare Konstrukte. Es gibt jedoch verschiedene Möglichkeiten, sie zu simulieren. Eine davon geht auf Simon Tatham zurück und ist auch wegen der Verwendung in dem populären SSH-Client PuTTY bekannt.
Da der Status in globalen Variablen vorgehalten wird, kann im Unterschied zu Python von jeder Koroutine jedoch immer nur eine Instanz ablaufen. Deswegen wird der Status in einem Thread-local Storage gespeichert, damit dennoch mehrere Instanzen von Koroutinen parallel ablaufen können, wenn man mehrere Threads gestartet hat.

### C++

Boost.Coroutine, offizieller Bestandteil der Boost-Libraries, ermöglicht die Verwendung von Koroutinen in C++. Im Gegensatz zu Python sind die Koroutinen von Boost.Coroutine jeweils mit einem Stack assoziiert. Somit sind Umschaltungen und Sprünge aus Unterfunktionen heraus möglich. Durch die interne Verwendung von Boost.Context werden ARM, MIPS, PowerPC, SPARC und X86 auf POSIX, Mac OS X und Windows unterstützt. C++ 20 unterstützt nativ die Implementierung von Koroutinen.
Mit der Version C++20 wurden Koroutinen in die Sprache integriert.

### C#
### D

D unterstützt gut in objektorientierter Umgebung nutzbare Koroutinen unter dem Namen Fibers. Die Umschaltung geschieht intern durch eine einfache Vertauschung des Stackpointers und ist bisher nur für x86 (Windows und Posix) und PowerPC verfügbar.
Vorteile sieht man besonders deutlich bei Verwendung von rekursiven Funktion wie beispielsweise bei der Traversierung von Binärbäumen.

### Tcl

Tool Command Language unterstützt gut nutzbare Koroutinen bereits im Sprachkern, wie grundsätzlich bei Tcl plattformunabhängig.

### PicoLisp

PicoLisp unterstützt Koroutinen als eingebautes Sprachelement (nur 64-bit version).