![]() |
VOOZH | about |
Prerequisite: Generators
We all are familiar with function which is also known as a subroutine, procedure, sub-process, etc. A function is a sequence of instructions packed as a unit to perform a certain task. When the logic of a complex function is divided into several self-contained steps that are themselves functions, then these functions are called helper functions or subroutines.
Subroutines in Python are called by the main function which is responsible for coordinating the use of these subroutines. Subroutines have a single entry point.
Coroutines are generalizations of subroutines. They are used for cooperative multitasking where a process voluntarily yield (give away) control periodically or when idle in order to enable multiple applications to be run simultaneously. The difference between coroutine and subroutine is :
Coroutine Vs Thread
Now you might be thinking how coroutine is different from threads, both seem to do the same job.
In the case of threads, itβs an operating system (or run time environment) that switches between threads according to the scheduler. While in the case of a coroutine, itβs the programmer and programming language which decides when to switch coroutines. Coroutines work cooperatively multitask by suspending and resuming at set points by the programmer.
Python Coroutine
In Python, coroutines are similar to generators but with few extra methods and slight changes in how we use yield statements. Generators produce data for iteration while coroutines can also consume data.
In Python 2.5, a slight modification to the yield statement was introduced, now yield can also be used as an expression. For example on the right side of the assignment -
line = (yield)
whatever value we send to coroutine is captured and returned by (yield) expression.
A value can be sent to the coroutine by send() method. For example, consider this coroutine which prints out the name having the prefix βDearβ in it. We will send names to coroutine using send() method.
Output:
Searching prefix:Dear
Dear Atul
Execution of Coroutine
The execution of the coroutine is similar to the generator. When we call coroutine nothing happens, it runs only in response to the next() and sends() method. This can be seen clearly in the above example, as only after calling __next__() method, our coroutine starts executing. After this call, execution advances to the first yield expression, now execution pauses and waits for the value to be sent to corou object. When the first value is sent to it, it checks for prefix and print name if prefix present. After printing the name, it goes through the loop until it encounters the name = (yield) expression again.
Closing a Coroutine
Coroutine might run indefinitely, to close coroutine close() method is used. When a coroutine is closed it generates GeneratorExit exception which can be caught in the except usual way. After closing the coroutine, if we try to send values, it will raise the StopIteration exception. Following is a simple example :
Output:
Searching prefix:Dear
Dear Atul
Closing coroutine!!
Chaining coroutines for creating pipeline
Coroutines can be used to set pipes. We can chain together coroutines and push data through the pipe using send() method. A pipe needs :
Following is a simple example of chaining -
Output:
I'm sink, i'll print tokens
Searching for ing
running
moving
Done with filtering!!
Done with printing!
References
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 you want to share more information about the topic discussed above.