Python3.7 高级编程之 async/await asyncio 通过asyncio.wait的使用

Python中的异步
# demo.py
import asyncio
import time

# Python 协程属于可等待对象,因此可以在其他协程中被等待 Python异步非阻塞雏形
async def nested():
    # time.sleep(2)
    await asyncio.sleep(2)
    print('我是异步内的任务,我已经完成了')
    return 45

async def main():
    print(time.strftime('%X'))
    start_time = time.time()
    task = asyncio.create_task(nested())  # 使用task去执行协程,就可以达到异步的效果,我们任务在这里是已经开启了协程,只是结果在其他位置等待。因此这个代码预期就是异步的。
    # await nested() # 这种调用会等待协程完成之后在继续向下执行,也就是协程会阻塞在这里,常用于同步协程
    # await task # 它会等待任务完成返回后 往下执行,如果在Python中想完成异步非阻塞 就需要先开启任务,然后执行其他操作,在某个地方等待task完成后返回 并退出
    print('我会不会先出现...')
    print('耗时:', time.time() - start_time)
    # nested()
    # print(await nested())
    # await task # 类似与线程的join方法,不同的时,这个放的位置决定着谁先执行,例如我们放到程序最后,将看到协程是最后才执行,await的意思可以看作是等待协程的结果。
    a = await task  # 等待的主要目的就是为了获取协程的结果
    print(a)
    # 注意这里的时间,和多线程类似的,当多线程没有join时,主线程会马上结束但是不会杀死子线程。这里也是一样,如果不等待协程的结果,主程序结束后不会杀死协程,协程将继续执行完毕
    print(time.strftime('%X'))

asyncio.run(main())

运行

python demo.py

预期的输出

22:17:16
我会不会先出现...
耗时: 1.2159347534179688e-05
我是异步内的任务,我已经完成了
45
22:17:18
对比使用gevent协程实现异步任务
import gevent
from gevent import monkey; monkey.patch_all()
import time


def nested():
    time.sleep(2)
    print('我是异步内的任务,我已经完成了')
    return 45

def main():
    start_time = time.time()
    print('我会不会先出现...')
    gevent.spawn(nested)
    time.sleep(3) # 这里停顿3秒的目的就是让主进程在三秒后结束,然后看协程是否被异步执行
    print('耗时:', time.time() - start_time)

if __name__ == '__main__':
    main()

得到的输出:

我会不会先出现...
我是异步内的任务,我已经完成了
耗时: 3.0009806156158447

再来修改使用asyncio的例子:

import asyncio
import time

# Python 协程属于可等待对象,因此可以在其他协程中被等待 Python异步非阻塞雏形
async def nested():
    time.sleep(2)
    # await asyncio.sleep(2)
    print('我是异步内的任务,我已经完成了')
    return 45

async def main():
    print(time.strftime('%X'))
    start_time = time.time()
    task = asyncio.create_task(nested())  # 使用task去执行协程,就可以达到异步的效果,我们任务在这里是已经开启了协程,只是结果在其他位置等待。因此这个代码预期就是异步的。
    # await nested() # 这种调用会等待协程完成之后在继续向下执行,也就是协程会阻塞在这里,常用于同步协程
    # await task # 它会等待任务完成返回后 往下执行,如果在Python中想完成异步非阻塞 就需要先开启任务,然后执行其他操作,在某个地方等待task完成后返回 并退出
    print('我会不会先出现...')
    print('耗时:', time.time() - start_time)
    # nested()
    # print(await nested())
    # await task # 类似与线程的join方法,不同的时,这个放的位置决定着谁先执行,例如我们放到程序最后,将看到协程是最后才执行,await的意思可以看作是等待协程的结果。
    # a = await task  # 等待的主要目的就是为了获取协程的结果
    # print(a)
    # 注意这里的时间,和多线程类似的,当多线程没有join时,主线程会马上结束但是不会杀死子线程。这里也是一样,如果不等待协程的结果,主程序结束后不会杀死协程,协程将继续执行完毕
    print(time.strftime('%X'))

asyncio.run(main())
time.sleep(3)

得到的输出:

22:30:23
我会不会先出现...
耗时: 1.049041748046875e-05
22:30:23
我是异步内的任务,我已经完成了

发现当使用time.sleep后任务也会被异步的执行,只是不在等待结果,此时不关心异步任务的执行结果

对比nodejs中的异步非阻塞代码
// demo.js
function timeout(ms) {
    setTimeout(function(){
        console.log('输出...')
        var end_time = (new Date().getTime()) / 1000
        console.log('程序真正完成时间:', end_time - start_time)
    },ms);
    
}
// nodejs 就是一个完全的非阻塞的
var start_time = (new Date().getTime()) / 1000
timeout(2000)
var end_time = (new Date().getTime()) / 1000
console.log('完成时间:', end_time - start_time)

运行

node demo.js

预期的输出

完成时间: 0.0009999275207519531
输出...
程序真正完成时间: 2.003000020980835
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haeasringnar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值