大家好,并发编程 进入第十章。
好了,今天的内容其实还挺多的,我准备了三天,到今天才整理完毕。希望大家看完,有所收获的,能给小明一个赞。这就是对小明最大的鼓励了。
为了更好地衔接这一节,我们先来回顾一下上一节的内容。
上一节「」,我们首先介绍了,如何创建一个协程对象.
主要有两种方法
通过async关键字,
通过@asyncio.coroutine 装饰函数。
然后有了协程对象,就需要一个事件循环容器来运行我们的协程。其主要的步骤有如下几点:
将协程对象转为task任务对象
定义一个事件循环对象容器用来存放task
将task任务扔进事件循环对象中并触发
为了让大家,对生成器和协程有一个更加清晰的认识,我还介绍了yield和async/await的区别。
最后,我们还讲了,如何给一个协程添加回调函数。
好了,用个形象的比喻,上一节,其实就只是讲了协程中的单任务。哈哈,是不是还挺难的?希望大家一定要多看几遍,多敲代码,不要光看哦。
那么这一节,我们就来看下,协程中的多任务。
. 本文目录
协程中的并发
协程中的嵌套
协程中的状态
gather与wait
. 协程中的并发
协程的并发,和线程一样。举个例子来说,就好像 一个人同时吃三个馒头,咬了第一个馒头一口,就得等这口咽下去,才能去啃第其他两个馒头。就这样交替换着吃。
asyncio实现并发,就需要多个协程来完成任务,每当有任务阻塞的时候就await,然后其他协程继续工作。
第一步,当然是创建多个协程的列表。
协程函数
async def do_some_work(x):
print('Waiting: ', x)
await asyncio.sleep(x)
return ‘Done after {}s’.format(x)
协程对象
coroutine1 = do_some_work(1)
coroutine2 = do_some_work(2)
coroutine3 = do_some_work(4)
将协程转成task,并组成list
tasks = [
asyncio.ensure_future(coroutine1),
asyncio.ensure_future(coroutine2),
asyncio.ensure_future(coroutine3)
]
第二步,如何将这些协程注册到事件循环中呢。
有两种方法,至于这两种方法什么区别,稍后会介绍。
使用asyncio.wait()
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))
使用asyncio.gather()
千万注意,这里的 「*」 不能省略
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(*tasks))
最后,return的结果,可以用task.result()查看。
for task in tasks:
print('Task ret: ', task.result())
完整代码如下
import asyncio
协程函数
async def do_some_work(x):
print('Waiting: ', x)
await asyncio.sleep(x)
return ‘Done after {}s’.format(x)
协程对象
coroutine1 = do_some_work(1)
coroutine2 = do_some_work(2)
coroutine3 = do_some