python协程 无能为力_关于Python的协程问题总结

协程其实就是可以由程序自主控制的线程

在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程

利用yield from 向生成器(协程)传送数据

# 传统的生产者-消费者是一个线程写消息,一个线程取消息,通过锁机制控制队列和等待,但一不小心就可能死锁。

# 如果改用协程,生产者生产消息后,直接通过yield跳转到消费者开始执行,待消费者执行完毕后,换回生产者继续生产,效率极高

defconsumer():

r= ''

whileTrue:

n= yieldrif notn:return

print('[CONSUMER] Consuming %s...' %n)

r= '200 OK'

defproduce(c):

c.send(None)

n=0while 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)

# 注意到consumer函数是一个generator,把一个consumer传入produce后:

# 首先调用c.send(None)启动生成器;

# 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

# consumer通过yield拿到消息,处理,又通过yield把结果传回;

# produce拿到consumer处理的结果,继续生产下一条消息;

# produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

# 整个流程无锁,由一个线程执行,produce和consumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务。

# 最后套用Donald Knuth的一句话总结协程的特点:

# “子程序就是协程的一种特例。”

理解上面的例子对python的协程理解很重要

下面是Python3.4支持协程的写法

importthreadingimportasyncio

@asyncio.coroutinedefhello(s):print(s)print('Hello world! (%s)' %threading.currentThread())yield from asyncio.sleep(1)print(s)print('Hello again! (%s)' %threading.currentThread())

loop=asyncio.get_event_loop()

tasks= [hello('w'), hello('e')]

loop.run_until_complete(hello('o'))#添加到task 表示一起执行

loop.run_until_complete(asyncio.wait(tasks))

tasks2= [hello('w'), hello('e'),hello('H')]print('++++++++++++++++++++')

loop.run_until_complete(asyncio.wait(tasks2))

loop.close()

# 由一个线程通过coroutine并发完成。

# async和await是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

# 把@asyncio.coroutine替换为async;

# 把yield from替换为await。

# 注意新语法只能用在Python 3.5以及后续版本,如果使用3.4版本,则仍需使用上一节的方案。

importasyncio

asyncdefhello():print("Hello world!")

r= await asyncio.sleep(1)print("Hello again!")

loop=asyncio.get_event_loop()

loop.run_until_complete(hello())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值