Coroutine

In computer science are coroutines (also coroutines ) a generalization of the concept of a procedure or function. The principal difference between coroutines and procedures is that coroutines interrupt their workflow and later be able to resume where they maintain their status.

Among the oldest programming languages ​​that support coroutines are simulation or Modula -2. Even modern languages ​​such as Python know similar concepts. However, in some popular languages ​​such as C or Java, the implementation is difficult. The term itself comes from Melvin Conway, who used it in 1963 in a publication on Compiler Construction. Donald Knuth called procedures as a special case of coroutines.

Implementation

Coroutines can be simulated in languages ​​that do not support them directly in general. This is a language- independent way to program comparable behavior, wait for the use of threads which run alternately and after relinquishing control until they get back in control. Another possibility, which will work in any language, the rolling of coroutines. Here, the coroutine must have its status will also provide ( for example, in a global variable ) and then jump on every call to the appropriate place their code. Since it is not possible in many programming languages ​​( for example, in a loop ) to jump into the middle of a block, such constructs must be in such a case is also replaced by simulations.

Python

The Python programming language supports the implementation of coroutines with the related construct of the generators. It may be temporarily interrupted with the keyword yield the expiry of a function. Internally, however, an object is created when you call such a generator function that lasts the status. This is realized by cached the full stack frame in loss of control and restored on resumption. The recovery is done by calling the next () method of the generator object.

Def fib ():         "" " Fibonacci sequence as a coroutine " ""         I1, I2 = 0, 1         while True:                 yield i2                 I1, I2 = I2 I1 I2   pay = fib ( ) for i in range (10 ):         print zahlen.next () In Python 2.5, the syntax of the yield keyword has been extended to allow the transfer of parameters in the other direction. This coroutines can be implemented entirely in Python.

C

C does not support coroutines or similar constructs. However, there are several ways to simulate them. One of them goes back to Simon Tatham, and is also known for its use in the popular PuTTY SSH client. In this approach exploits the fact that the case statements must not be at C on the same level as the corresponding switch statement:

# include   / / Fibonacci sequence as a coroutine int fib ( ) {      static int i1 = 0, i2 = 1, state = 0;      int tmp;        switch (state) {      case 0: while (1 ) { state = 1; return i2;        case 1: / / Belongs to switch (state) tmp = i2; i2 = i1 i2; i1 = tmp; } / / While      } / / Switch }   int main () {      int i;        for (i = 0; i < 10; i ) printf ("% d \ n", fib ());      return 0; } This construction can be presented visually a little better through the use of macros. If the status is maintained in a static variable, but in contrast to Python from each coroutine can always run only one instance. If the status is, however, stored in a thread -local storage, but several instances of coroutines can run in parallel.

C

Boost.Coroutine, since version 1.53 official part of the Boost libraries, allows the use of coroutines in C . Unlike Python are the coroutines of Boost.Coroutine stack -full, that is, there is associated with each coroutine a stack. Thus switching / jumps sub-functions are out possible. The internal use of Boost.Context ARM, MIPS, PowerPC, SPARC and X86 on POSIX, Mac OS X and Windows are supported.

# include # include   # include # include   int main () {      boost :: coroutines :: coroutine < int ( ) > c (          [ &] ( Boost :: coroutines :: coroutine < void ( int) > & c ) {              int first = 1, second = 1;              for (int i = 0; i < 10; i ) {                  int third = first second;                  first = second;                  second = third;                  c (third );              }          });        for ( auto i: c ) {          std :: cout << i << "";      }        std :: cout << " \ Ndone " << std :: endl;        return EXIT_SUCCESS; } D

D supports good usable in object-oriented environment coroutines about the alternative standard library Tango under the name Fibers. Switching is done internally by a simple permutation of the stack pointer and is so far only available for x86 (Windows and Posix ) and PowerPC.

Import tango.core.Thread; import tango.io.Stdout;   class Fibonacci generator {   private fiber fiber; private uint fibonacci = 1;   private void run () { oldFibonacci uint = 0; uint tmp;   while ( true) { Fiber.yield (); tmp = fibonacci; fibonacci = oldFibonacci; oldFibonacci = tmp; } }   this () { fiber = new Fiber ( & run ); }   uint next () { fiber.call (); return fibonacci; } }   void main () { Fibonacci generator fibGen = new Fibonacci generator ();   for ( uint i = 0; i < 10; i ) { Stdout.format ("{ } \ n", fibGen.next ()); } } Advantages can be seen particularly clearly with the use of a recursive function, such as when traversal of binary trees.

Credentials

  • Programming language element
203428
de