栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python协程asynio深入解析

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python协程asynio深入解析

先上代码:

import asyncio

async def test():
    print('one')
    await asyncio.sleep(1)
    print('two')

async def main():
    a=asyncio.create_task(test())
    b=asyncio.create_task(test())
    c=asyncio.create_task(test())
    print('hello')
    await a,b,c

asyncio.run(main())

运行结果很完美:

hello
one
one
one
two
two
two

修改代码,删除await a,b,c

import asyncio

async def test():
    print('one')
    await asyncio.sleep(1)
    print('two')

async def main():
    a=asyncio.create_task(test())
    b=asyncio.create_task(test())
    c=asyncio.create_task(test())
    print('hello')

asyncio.run(main())
hello
one
one
one

Process finished with exit code 0

可以发现test()执行了,但是没有'two'。再次修改代码增加

import asyncio

async def test():
    print('one')
    await asyncio.sleep(1)
    print('two')

async def main():
    a=asyncio.create_task(test())
    b=asyncio.create_task(test())
    c=asyncio.create_task(test())
    print('hello')
    await asyncio.sleep(1)

asyncio.run(main())

结果为:

hello
one
one
one
two
two
two

实际执行过程为:

1、asyncio.run(main()),程序进入 main() 函数,事件循环开启;

2、任务a、b、c被创建,并进入事件循环等待运行;运行到 print时,输出 'hello';

3、如果运行到await,则从当前的主任务中切出,事件调度器开始调度 a

4、在a中打印'one',运行到 await asyncio.sleep(1),从当前任务切出,事件调度器开始调度 b

5、在b中打印'one',运行到 await asyncio.sleep(1),从当前任务切出,事件调度器开始调度 c

6、在c中打印'one',运行到 await asyncio.sleep(1),从当前任务切出。

7、如果后续程序,如第二段代码中没有await,主程序认为程序运行完毕,则结束进程,不会打印'two'。

8、如果await a,b,c 则主程序会等待a、b、c执行完毕。

9、如果main函数中没有await a,b,c,而是await  asyncio.sleep(1),则a、b、c依旧有时间执行完程序,所以会输出'two',但如果await  asyncio.sleep(0.5)则a、b、c在执行完毕前程序就会被杀死,所以依旧不会输出'two'。

如果我们想给某些协程任务限定运行时间,一旦超时就取消,或者协程运行错误应该怎么处理呢?这里贴上某位大佬的代码:

import asyncio

async def worker_1():
    await asyncio.sleep(1)
    return 1

async def worker_2():
    await asyncio.sleep(2)
    return 2 / 0

async def worker_3():
    await asyncio.sleep(3)
    return 3

async def main():
    task_1 = asyncio.create_task(worker_1())
    task_2 = asyncio.create_task(worker_2())
    task_3 = asyncio.create_task(worker_3())

    await asyncio.sleep(2)
    task_3.cancel()

    res = await asyncio.gather(task_1, task_2, task_3, return_exceptions=True)
    print(res)

%time asyncio.run(main())

########## 输出 ##########

[1, ZeroDivisionError('division by zero'), CancelledError()]
Wall time: 2 s

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/488631.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号