Producer consumer problem in coroutine
文章目录
What is coroutine
As the name implies, coroutine refers to co-operative routine. It allows you to suspending and resuming execution at different locations. So, it’s essentially just context switching. Not surprisingly, coroutine is implemented in primitives like setjmp/longjump or ucontext in low level.
In many senarioes, coroutine is a more light-weight alternative of threads. For programming languages with GIL (like Python), coroutine would used to handle concurrency.
Producer and consumer problem
Let’s take a look at classic “producer-consumer” problem. At each time, one coroutine produce products and add them into queue, the other coroutine take products from queue and use it (hmm, sounds like video buffering, right?).
The code below assumes you already have some knowledge of generator.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import time
import random
def coroutine(func):
# A wrapper to convert function into generator
# From David Beazley
def start(*args,**kwargs):
cr = func(*args,**kwargs)
cr.next()
return cr
return start
def producer(target):
while True:
time.sleep(1)
data = random.randint(1, 10)
print ("# producer: sending data {}".format(data))
target.send(data)
def consumer():
while True:
data = yield
print ("# consumer: receving data {}".format(data))
if __name__ == '__main__':
g_consumer = consumer()
producer(g_consumer)
Simple enough, send()
is a built-in function of generator. The producer send data to consumer, consumer receives data from yield
.
Coroutine usage
Yes, the famous concurrency library gevent is based on coroutine.
Reference and Recommended Reading:
PEP 342: Coroutines via Enhanced Generators
General concepts: concurrency, parallelism, threads and processes