Coroutines are general control structures where flow control is cooperatively passed between two different routines without returning.
If you have used Python or C#, you may know that there is a keyword called yield that allows a loop back and forth between the caller and the called function until the caller is not done with the function or the function terminates because of some logic it is given.
Sample Python3 code of yield.
Python
def rangeN(a, b):
i = a
while (i < b):
yield i
i + = 1
for i in rangeN( 1 , 5 ):
print (i)
|
This code demonstrates how the yield works and gives a brief idea about how the control is changed between the caller and callee.
Why Coroutines are needed?
To read a file and parse it while reading into some meaningful data, you can either read step by step at each line, which is fine. You may also load the entire content in memory, which won’t be recommended for large text cases e.g text editors like Microsoft Word or in modern systems just use Pipes.
In The Art of Computer Programming, Donald Knuth presents a solution to this sort of problem. His answer is to throw away the stack concept completely. Stop thinking of one process as the caller and the other as the callee, and start thinking of them as cooperating equals. So we can now try and see how to achieve the same in C.
function read():
/* reads the content in the desired number
of steps and returns back control to parser
but saves its own state of function. */
function parse():
a = read()
while (a)
{
// do something
a = read()
}
Well, in practice this structure looks very similar to the caller-callee structure of C. But what we require here is that the reader must remember its state. It must remember where it was last time when it did the job and should also be re-settable.
How to implement Coroutines in C?
The challenge is to have coroutines in C language which is itself a stack-based language i.e in every response to a function call in C language there is a stack being initialized that keeps track of all its variables and constants and gets destroyed when the function call ends.
C
int read( void )
{
int i;
for (i = 0; i < 10; i++)
return i;
}
|
We need to do two things:
- Resume control to its last state
- Make data persist through calls
Both of these above problems should be solved by the use of static variables. But how to remember the state and also return back to the same execution state as before i.e., the lines of code after the return or the loop. We can use GOTO statements. Which is not recommended generally. Here, we can try something called Duff’s device. So we finally move on to the solution code.
C++
#include <iostream>
using namespace std;
int range( int a, int b)
{
static long long int i;
static int state = 0;
switch (state) {
case 0:
state = 1;
for (i = a; i < b; i++) {
return i;
case 1:
cout << "control at range"
<< endl;
}
}
state = 0;
return 0;
}
int main()
{
int i;
for (; i = range(1, 5);)
cout << "control at main :" << i << endl;
return 0;
}
|
C
#include<stdio.h>
int range( int a, int b)
{
static long long int i;
static int state = 0;
switch (state)
{
case 0:
state = 1;
for (i = a; i < b; i++)
{
return i;
case 1:;
}
}
state = 0;
return 0;
}
int main()
{
int i;
for (; i=range(1, 5);)
printf ( "control at main :%d\n" , i);
return 0;
}
|
Output
control at main :1
control at range
control at main :2
control at range
control at main :3
control at range
control at main :4
control at range
The solution uses our understanding of Duff’s device and has it play with it. We can now essentially have multiple return statements inside the for loop and each time we return to a different state of execution if it’s programmed to do so. This implementation only mimics the range function of python which is also based on coroutine since it returns generator objects as of Python3.
Source: Coroutines in C by Simon Tatham
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above.
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
17 May, 2022
Like Article
Save Article