python协程概念

一、什么是coroutine

  • 使用async/await 语法来声明
  • 普通函数前加上async后,一般被称为 coroutine function
  • 函数不能再使用 function()来进行调用,这种方式返回的是coroutine object,是不能执行到函数里面的代码的
  • 要调用async function 需要使用asyncio.run(coroutin object)
import asyncio

async def main():
    print('hello')
    await asyncio.sleep(1)
    print('world')

asyncio.run(main())




 print(main())
<coroutine object main at 0x1053bb7c8>
RuntimeWarning: Enable tracemalloc to get the object allocation traceback

await 后面可以跟coroutine 或者是task

  • 如果await 后面的是coroutine,①会把coroutine包装成一个task,并加入到事件循环中,②会等待它执行完毕,③拿到返回值
  • 如果await 后面跟的是task,就省去了包装成task的步骤,并且就会把控制权交还给event loop 来决定是否执行其他的任务

二、多个协程函数的并发运行

  1. await 后面是coroutine
import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)

async def main():
    print(f"started at {time.strftime('%X')}")

    await say_after(1, 'hello')  # 这里await 后面是coroutine ,遇到await后会等待这个执行完成后,才会把控制权交还给event loop,所以这里相当于是异步里的同步函数了
    await say_after(2, 'world')

    print(f"finished at {time.strftime('%X')}")

asyncio.run(main())

image

  1. await 后面是task
import asyncio
import time

async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)
async def main():
    task1 = asyncio.create_task(
        say_after(1, 'hello'))

    task2 = asyncio.create_task(
        say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await task1
    await task2

    print(f"finished at {time.strftime('%X')}")
asyncio.run(main())

image
3.使用asyncio.gather()来并发,参数可以是coroutine,也可以是task对象

  • 参数是task
import asyncio
import time


async def say_after(delay, what):
    await asyncio.sleep(delay)
    print(what)


async def main():
    task1 = asyncio.create_task(
        say_after(1, 'hello'))

    task2 = asyncio.create_task(
        say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await asyncio.gather(task1,task2)

    print(f"finished at {time.strftime('%X')}")


asyncio.run(main())
  • 参数是coroutine
async def main():
    # task1 = asyncio.create_task(
    #     say_after(1, 'hello'))
    #
    # task2 = asyncio.create_task(
    #     say_after(2, 'world'))

    print(f"started at {time.strftime('%X')}")

    # Wait until both tasks are completed (should take
    # around 2 seconds.)
    await asyncio.gather(say_after(1, 'hello'),say_after(2, 'world')) #会把coroutine 包装成task

    print(f"finished at {time.strftime('%X')}")

三、获取协程函数的返回值

import asyncio

async def hello():
    await asyncio.sleep(1)
    return 9999

async def main():
    result = await hello()  # 使用await获取返回值,赋值给变量
    print(result)

asyncio.run(main())
posted @ 2023-09-19 16:58  弩哥++  阅读(16)  评论(0编辑  收藏  举报