协程与asyncio

1.协程

协程不是计算机提供的,程序员人为创造的

用户态的上下文切换技术

2.asyncio

在python3.4及之后的版本支持

2.1事件循环

理解成一个死循环,检测并执行某些代码

复制代码
#伪代码
任务列表 = [ 任务1, 任务2, 任务3 ...]
while True:
    可执行的任务列表,已完成的任务列表 = 去任务列表中检查所有的任务,将可执行和已完成的任务安徽
    for 就绪任务 in 可执行的任务猎豹
        执行就绪任务
    for 已完成的任务 in 已完成的任务列表
        在任务列表中移除 已完成的任务
    如果 任务列表 中的任务都已完成,则终止循环
复制代码

 

2.2快速上手

协程函数,定义函数的时候async def 函数名

协程对象,执行协程函数得到的协程对象

async def func():
    pass

result = func()

注意:执行协程函数创建协程对象,函数内部代码不会执行

如果想要运行协程函数内部代码,必须要将携程对象交给事件循环来处理

复制代码
复制代码
def func():
    print("协程!!!!!")

result = func()


#loop = asyncio.get_event_loop()
# 时间循环执行
#loop.run_until_complete(result) #python3.7之后支持 asyncio.run(result)
复制代码
复制代码

3.3 await

await + 可等待的对象{协程对象 Future对象 Task对象 -------->IO等待}

示例1:

import asyncio

async def func():
    print("来玩啊")
    response = await asyncio.sleep(2)
    print("结束",response)

asyncio.run(func())

结果:

执行协程函数内部代码
start
end
IO请求结果1,结果为: 返回值

示例2:

复制代码
import asyncio

async def others():
    print("start")
    await asyncio.sleep(2)
    print("end")
    return "返回值"

async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后在继续往下执行,当协程挂起时,事件循环可以去执行其他协程(任务)
    response = await others()
    print("IO请求结果,结果为:", response)

asyncio.run(func())
复制代码

示例3:

复制代码
import asyncio

async def others():
    print("start")
    await asyncio.sleep(2)
    print("end")
    return "返回值"

async def func():
    print("执行协程函数内部代码")
    # 遇到IO操作挂起当前协程(任务),等IO操作完成之后在继续往下执行,当协程挂起时,事件循环可以去执行其他协程(任务)
    response1 = await others()
    print("IO请求结果,结果为:", response1)

    response2 = await others()
    print("IO请求结果,结果为:", response2)

asyncio.run(func())
复制代码

结果:

执行协程函数内部代码
start
end
IO请求结果1,结果为: 返回值
start
end
IO请求结果2,结果为: 返回值

 

await就是等待对象的值得到结果之后再继续向下走,将协程对象变成task对象,获取返回值

3.4Task对象

在时间循环中添加多个任务

通过asyncio.create_task(协程对象)的方式创建Task对象,这样可以让协程加入时间循环中等待被调度执行,除了使用asyncio.create_task(协程对象)函数外,还可以使用低层级的loop.create_task()或ensure_future()函数

注意:asyncio.create_task 函数是在python3.7中被加入,在python3.7前可以改用asyncio.ensure_future 函数

复制代码
import asyncio

async def func():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "返回值"

async def main():
    print("main开始")

    #创建task对象,将当前执行func函数任务添加到事件循环中
    task1 = asyncio.create_task(func())

    task2 = asyncio.create_task(func())

    print("main结束")

    # 当执行某协程遇到IO操作时,会自动切换执行其他任务,
    # 此处的await时等待相对应的协程全部执行完毕并获取结果
    ret1 = await task1
    ret2 = await task2
    print(ret1,ret2)

if __name__ == '__main__':
    asyncio.run(main())
复制代码

结果:

main开始
main结束
1
1
2
2
返回值 返回值

示例2:

 

复制代码
import asyncio


async def func():
    print(1)
    await asyncio.sleep(2)
    print(2)
    return "返回值"


async def main():
    print("main开始")

    # 创建task对象,将当前执行func函数任务添加到事件循环中
    task_list = [asyncio.create_task(func()), asyncio.create_task(func())]

    print("main结束")

    done, pending = await asyncio.wait(task_list, timeout=None)
    print(done)
    print(pending)



if __name__ == '__main__':
    asyncio.run(main())
复制代码

结果:

main开始
main结束
1
1
2
2
{<Task finished name='Task-2' coro=<func() done, defined at C:\Users\dingwei\PycharmProjects\fastapi\test.py:4> result='返回值'>, <Task finished name='Task-3' coro=<func() done, defined at C:\Users\dingwei\PycharmProjects\fastapi\test.py:4> result='返回值'>}
set()

 

posted @   斯瓦勃洛  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示