协程(Coroutine)在执行过程中可中断去执行其他任务,执行完毕后再回来继续原先的操作。可以理解为两个或多个程序协同工作
协程特点在于单线程执行。
优势一:具有极高的执行效率,因为在任务切换的时候是程序之间的切换(由程序自身控制)而不是线程间的切换,所以没有线程切换导致的额外开销(时间浪费),线程越多,携程性能优势越明显。
优势二:由于是单线程工作,没有多线程需要考虑的同时写变量冲突,所以不需要多线程的锁机制,故执行效率比多线程更高。
常利用多进程(利用多核)+协程来获取更高的性能。
讲工作原理前先了解yield,它不仅可以返回一个值,还可以接收调用者发出的参数。
代码如下:
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[CONSUMER] Consuming %s...' % n)
r = '200 OK'
def produce(c):
c.send(None)
n = 0
while n < 5:
n = n + 1
print('[PRODUCER] Producing %s...' % n)
r = c.send(n)
print('[PRODUCER] Consumer return: %s' % r)
c.close()
c = consumer()
produce(c)
运行结果:
[PRODUCER] Producing 1...
[CONSUMER] Consuming 1...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 2...
[CONSUMER] Consuming 2...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 3...
[CONSUMER] Consuming 3...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 4...
[CONSUMER] Consuming 4...
[PRODUCER] Consumer return: 200 OK
[PRODUCER] Producing 5...
[CONSUMER] Consuming 5...
[PRODUCER] Consumer return: 200 OK
整个代码关键点在于n = yield r
和r = c.send(n)
这两处。
每次运行到r = c.send(n)的时候,先执行=右边部分:将n通过send()传入consumer()中,即n=send(n),继续往下执行到将200 ok
赋给r再一次运行到n = yield r
的时候,yield会返回r;接着又切换到了produce()函数,返回的r被赋给了r。这就是整个的运行过程。
总结:
可以把n = yield r理解为一个接收机,可以接受外部通过send()传进来的值。每次运行到这里,会先执行yield r返回r,再把返回值赋给n。