通过 asyncio 尝试python最基础的异步操作

目标

之前翻译的 Andrew Crozier 使用 asyncio 的一个指南 里有对 python 异步相关的关键词,以及 asyncio 的接口的基础介绍与范例。

本篇目标是实践 asyncio 的最基础的操作。

无异步的一般情况

为了说明“异步”的特点,先看下无异步的情况,即一般的情况:

DoSomething是个测试函数,假设了某人用了几秒做某事,而且做事的时候每隔1秒都会打印信息:

import time

#假设某人用了几秒做某事:
def DoSomething(someone, seconds):
    for i in range(seconds):
        time.sleep(1)                               #等待1秒模拟在做某事
        print(someone + " doing things:" + str(i))   #间隔1秒打印信息

if __name__=='__main__':
    DoSomething("jack",3)
    DoSomething("ming",4)

那么,当直接调用两次这个函数,分别让 jack 做3秒,ming 做4秒时。理所当然会有下面的输出:

jack doing things:0
jack doing things:1
jack doing things:2
ming doing things:0
ming doing things:1
ming doing things:2
ming doing things:3

而如果想要 jack 和 ming 同时做事,那就需要异步的操作了:

异步的情况(并行)

首先需要在函数名前加async来表明它是个异步函数。接着就要用到 asyncio 库中的一些接口了:

import asyncio

#假设某人用了几秒做某事:
async def DoSomething(someone, seconds):
    for i in range(seconds):
        await asyncio.sleep(1)                      #等待1秒模拟在做某事
        print(someone + " doing things:" + str(i))   #间隔1秒打印信息

if __name__=='__main__':
    #获得 event loop:
    loop = asyncio.get_event_loop()
    #待执行的异步函数:
    tasks = [
        asyncio.ensure_future(DoSomething("jack",3)),
        asyncio.ensure_future(DoSomething("ming",4)), 
    ]
    #开始执行:
    loop.run_until_complete(asyncio.gather(*tasks))

简单来说:

  • 先通过asyncio.get_event_loop()获得 event loop
  • 然后通过 asyncio.ensure_future 获得任务对象
  • 再用asyncio.gather收集要执行的任务对象的列表
  • 最后调用 event loop 的 run_until_complete 来执行这些任务。

代码执行后,将会看到:

jack doing things:0
ming doing things:0
jack doing things:1
ming doing things:1
jack doing things:2
ming doing things:2
ming doing things:3

可以看出他们确实是并行执行了。

另一种写法

Andrew Crozier 使用 asyncio 的一个指南 中出现的范例是另一种写法,效果是一样的,但需要更新的python版本。
使用那个写法改写后代码如下:

import asyncio

#假设某人用了几秒做某事:
async def DoSomething(someone, seconds):
    for i in range(seconds):
        await asyncio.sleep(1)                      #等待1秒模拟在做某事
        print(someone + "doing things:" + str(i))   #间隔1秒打印信息

async def DoAllWork():
    #待执行的异步函数:
    await asyncio.gather(
        DoSomething("jack",3),
        DoSomething("ming",4), 
    )

if __name__=='__main__':
    #开始执行:
    asyncio.run(DoAllWork())

猜你喜欢

转载自blog.csdn.net/u013412391/article/details/127306210