python 协程

import time
import random
import asyncio
async def waiter(name):
	for _ in range(6):
		time_to_sleep = random.randint(1, 3) / 4
		time.sleep(time_to_sleep)
		#await asyncio.sleep(time_to_sleep)
		print(
"{} waited {} seconds"
"".format(name, time_to_sleep)
)
async def main():
	await asyncio.wait([waiter("foo"), waiter("bar")])

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

两个协程中的代码都得到全部执行,执行的先后顺序不定,可能先执行foo,也可能先执行bar.(实验时,貌似是固定的顺序,可以改下循环里的次数)

4次时:

D:\Anaconda\python.exe D:/pythonTest/hello/testcoroutine.py
foo waited 0.5 seconds
foo waited 0.25 seconds
foo waited 0.25 seconds
foo waited 0.5 seconds
bar waited 0.75 seconds
bar waited 0.25 seconds
bar waited 0.5 seconds
bar waited 0.75 seconds

Process finished with exit code 0

6次时:

D:\Anaconda\python.exe D:/pythonTest/hello/testcoroutine.py
bar waited 0.5 seconds
bar waited 0.5 seconds
bar waited 0.5 seconds
bar waited 0.5 seconds
bar waited 0.5 seconds
bar waited 0.75 seconds
foo waited 0.25 seconds
foo waited 0.5 seconds
foo waited 0.25 seconds
foo waited 0.5 seconds
foo waited 0.5 seconds
foo waited 0.75 seconds

Process finished with exit code 0

这里因为time.sleep 是阻塞的,所以要么是foo 全部打印完,要么是bar 全部打印完。

如果将 time.sleep注释掉,采用下边被注释掉的await asycio.sleep,打印结果可能如下:

D:\Anaconda\python.exe D:/pythonTest/hello/testcoroutine.py
foo waited 0.25 seconds
bar waited 0.5 seconds
bar waited 0.25 seconds
foo waited 0.5 seconds
foo waited 0.5 seconds
bar waited 0.75 seconds
foo waited 0.25 seconds
foo waited 0.25 seconds
bar waited 0.75 seconds
foo waited 0.5 seconds
bar waited 0.75 seconds
bar waited 0.5 seconds

Process finished with exit code 0

asycio.sleep 也被加入到事件循环中被调度,所以出现 foo 和 bar 的交叉打印。每次运行到 await 处,此协程将await后的对象传递给事件循环,等待结果的返回。然后控制流进入事件循环处理事件。处理完事件,将结果返回给等待该结果的协程,接着执行获取该结果的协程。

foo 和 bar交替执行,主动让出控制流。这与普通的函数调用中的调用者与被调用者的关系是完全不同的:被调用者的状态在控制流回到调用者之后完全丢弃,谈不上再恢复。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值