协程
协程是比线程更加微小的结构,称为Coroutine。一般的函数调用是通过栈实现的,一个线程就是执行一个函数,函数的调用总是一个入口,一个返回,调用顺序是明确的。而协程则不同,协程看上去也是函数,但在执行过程中在函数内部可以中断,转而执行其他的函数,在适当的时候在返回来继续执行。
协程的特点是在一个线程执行,其优势就是有极高的执行效率。因为函数切换不是线程切换,因此没有线程切换的开销,和多线程相比,线程数越多,协程的性能优势就越明显。此外,协程不需要线程锁的机制,因为只有一个线程,所以也不存在写变量冲突。
在利用多核CPU方面,可以采用多进程+协程的方式,充分利用多核并且发挥协程的高效率。Python对协程的支持是通过生成器实现的。
Python的yield
不仅可以返回一个值,还可以接收调用者发出的参数。
以下示例使用生产者-消费者模式演示了协程的使用。
def consumer():
r = ''
while True:
n = yield r
if not n:
return
print('[CONSUMER] Consuming {}'.format(n))
r = '200 ok'
def produce(c):
c.send(None)
n = 0
while n < 5:
n += 1
print('[PORODUCER] Producing {}'.format(n))
r = c.send(n)
print('[PRODUCER] Consumer return {}'.format(r))
c.close()
c = consumer()
produce(c)
这里需要注意以下几点:
consumer
是一个生成器,将其传入producer
后,调用c.send(None)
启动生成器;- 一旦产生了内容,通过
c.send(n)
切换到consumer
的执行; consumer
通过yield
拿到消息,处理后又通过yield
传回结果;producer
拿到consumer
处理的结果,继续产生下一条消息;producer
结束生产时,调用c.close()
关闭consumer
结束整个过程。
这整个运行过程中是不需要锁的,而且在同一个线程中执行。