其他分享
首页 > 其他分享> > asyncio

asyncio

作者:互联网

asyncio还是一个python的单进程单线程程序,比较适合处理那些需要等待的任务。比如网络通信。
async的核心是一个事件循环event loop。event loop控制着任务的调度运行。同时执行的任务只有一个不存在系统级上下文切换和线程不一样。需要每个task告知event loop 运行完成可以让其他task运行。不存在竞争冒险问题,可以名确知道每个task什么时候停止运算。

coroutine

  1. coroutine function:由async修饰的函数
async def func():
    pass
  1. coroutine object: 调用coroutine function的返回结果,但不会运行coroutine function里面的代码。
    要想运行coroutine代码,需要进入事件循环,然后把coroutine转换成task

asyncio.run(coroutine object)

import asyncio

async def coru_f(i):
    await asyncio.sleep(1) 
    return i


async def coroutine_function(index):
    print(f"coroutine {index} start")
    var = await coru_f(index)
    # await把coroutine object转换为一个新的task,并向event loop注册这个task
    # 并告诉event loop 需要等待后面的新的task运行完才会继续运行当前task
    # 然后在当前task等待新task运行完成时,event loop 会运行其他task
    # 当event loop再次调度运行这个task值时,会获取新的task的返回值
    # 并将其赋值给var
    print(var)
    print(f"exit coroutine {index}")

async def main():
    await coroutine_function(1)
    await coroutine_function(2)

if __name__ == "__main__":
    coroutine_obj = main()
    # 创建event loop,把coroutine object转换成task,然后运行task
    asyncio.run(coroutine_obj)  # asyncio.run是串行执行
    

asyncio.creat_task

asyncio.run和await只能串行执行,asyncio.creat_task同样接收一个coroutine object,会把coroutine object 转换为一个task,返回这个task并且向event loop注册这个task

import asyncio 
import time

async def cor_fun(delay, string, index):
    print(f"task{index} started at {time.strftime('%X')}")
    await asyncio.sleep(delay) # 告诉event loop需要等待asyncio.sleep(delay) 运行完成,控制权交回给event loop, event loop就会调度其他task运行
    print(string)
    print(f"task{index} finished at {time.strftime('%X')}\n")

async def main():
    task1 = asyncio.create_task(
        cor_fun(1, "hello", 1)
    )  # 创建task并不会把控制权交回给event loop,所以不会调度运行新建的task,会继续运行main这个coroutine function的代码
    task2 = asyncio.create_task(
        cor_fun(2, "world", 2)
    )
    print(f"started at {time.strftime('%X')}\n")
    await task1 # 告诉event loop需要等待task1 运行完成,控制权交回给event loop, event loop就会调度其他task运行
    await task2
    print(f"finished at {time.strftime('%X')}\n")

asyncio.run(main())
# started at 23:52:09

# task1 started at 23:52:09
# task2 started at 23:52:09
# hello
# task1 finished at 23:52:10

# world
# task2 finished at 23:52:11

# finished at 23:52:11

asyncio.gather

asyncio.gather接收多个task或coroutine或future,把多个task组合起来,返回一个future对象

import asyncio
import time

from pyrsistent import m 


async def sum_(n):
    print(f"calculate 1**3+.....+{n}**3 at {time.strftime('%X')}")
    await asyncio.sleep(n//3)
    ans = sum([i**3 for i in range(1,n+1)])
    print(f"finished calculating 1**3+.....+n**3 at {time.strftime('%X')}")
    return ans 

async def main():
    print(f"started at {time.strftime('%X')}")
    res = await asyncio.gather(
        sum_(5),
        sum_(10),
        sum_(3)
    )  
    # future对象也可以await,await futer 告诉event loop 需要等待里面每一个task运行完成
    # 同时把所有task的返回值放到一个list中返回
    print(res)
    print(f"finished at {time.strftime('%X')}")

if __name__ == "__main__":
    asyncio.run(main())
    
# started at 00:08:12
# calculate 1**3+.....+n**3 at 00:08:12
# calculate 1**3+.....+n**3 at 00:08:12
# calculate 1**3+.....+n**3 at 00:08:12
# finished calculating 1**3+.....+n**3 at 00:08:13
# finished calculating 1**3+.....+n**3 at 00:08:13
# finished calculating 1**3+.....+n**3 at 00:08:15
# [225, 3025, 36]
# finished at 00:08:15

标签:task,coroutine,print,event,loop,asyncio
来源: https://www.cnblogs.com/baiyutang7/p/16410585.html