asyncio.create_task()

asyncio.create_task(coro) 详细介绍

asyncio.create_task()asyncio 模块中的一个重要函数,它将一个协程(coro)包装成一个 任务(Task) 并将其调度到事件循环中执行。它允许协程以并发的方式运行,而不需要显式地使用 await 来等待执行。

一、asyncio.create_task(coro) 的作用

  • 调度执行:asyncio.create_task() 会立即将传入的协程对象 coro 作为任务调度到事件循环中去执行,而不阻塞当前协程的执行。
  • 返回 Task 对象:该函数返回一个 Task 对象,表示这个任务的状态,可以通过它获取任务的执行结果或取消任务。

📌 用法:

asyncio.create_task(coro)

二、基本示例

import asyncio

async def say_hello():
    await asyncio.sleep(1)
    print("Hello")

async def main():
    # 创建任务
    task = asyncio.create_task(say_hello())
    
    print("Task created, now doing something else")
    
    # 可以做一些其他事情
    await asyncio.sleep(0.5)
    print("Halfway done...")
    
    # 等待任务完成
    await task
    print("Task finished!")

asyncio.run(main())

解释:

  1. asyncio.create_task(say_hello()) 会将 say_hello() 协程立即调度到事件循环中去执行,但它不会立即执行。
  2. 在 main() 中,创建任务后,程序并不会等待任务结束,而是继续执行后续代码 await asyncio.sleep(0.5)。
  3. 最后,await task 会等待 task 完成,确保任务执行完毕。

三、为何使用 create_task

  1. 并发执行:你可以同时运行多个任务,而不需要显式地等待每个任务完成。create_task 会将任务添加到事件循环中,允许它们并发执行。
  2. 提高效率:使用 asyncio.create_task 可以让多个任务并发执行,从而提高程序的效率,尤其是在 IO 密集型操作时,比如网络请求、数据库查询等。

四、与 await 的区别

  • await 会挂起当前协程,直到目标协程完成,而 create_task() 立即启动协程的执行,不会挂起当前函数的执行。
  • 如果直接使用 await 执行协程,程序会阻塞,直到该协程完成。而 create_task() 则是非阻塞的,它允许你在等待协程的同时执行其他任务。

📌 例子对比:

import asyncio

async def job(n):
    await asyncio.sleep(n)
    return f"Job {n} done"

# 1. 使用 await(同步顺序执行)
async def main_with_await():
    result1 = await job(1)
    print(result1)
    result2 = await job(2)
    print(result2)

# 2. 使用 create_task(并发执行)
async def main_with_create_task():
    task1 = asyncio.create_task(job(1))
    task2 = asyncio.create_task(job(2))
    result1 = await task1
    result2 = await task2
    print(result1)
    print(result2)

# 执行
asyncio.run(main_with_await())  # 会顺序打印
# asyncio.run(main_with_create_task())  # 会并发打印
  • main_with_await() 中,job(1) 完成后才会执行 job(2),是顺序执行。
  • main_with_create_task() 中,job(1) 和 job(2) 是并发执行的,await task1 和 await task2 等待结果时它们已经在后台执行。

五、asyncio.create_task() 的典型应用

1. 同时处理多个任务

asyncio.create_task() 使得多个任务可以并发执行,通常在需要同时处理多个IO密集型操作时非常有用。例如,进行多个异步网络请求时:

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

async def main():
    task1 = asyncio.create_task(fetch('https://example.com'))
    task2 = asyncio.create_task(fetch('https://example.org'))

    # 等待并获取结果
    result1 = await task1
    result2 = await task2

    print("Task 1 result:", result1[:100])  # 打印前100个字符
    print("Task 2 result:", result2[:100])

asyncio.run(main())

在这个例子中,fetch() 任务是并发执行的,而不会因为第一个 fetch() 任务的执行而阻塞第二个 fetch()

2. 并行执行多个 I/O 操作

比如同时读取多个文件或执行多个数据库查询,这时可以通过 create_task() 实现并发执行:

import asyncio

async def read_file(file_name):
    await asyncio.sleep(1)  # 模拟文件读取延迟
    return f"Content of {file_name}"

async def main():
    tasks = [
        asyncio.create_task(read_file("file1.txt")),
        asyncio.create_task(read_file("file2.txt")),
        asyncio.create_task(read_file("file3.txt"))
    ]

    results = await asyncio.gather(*tasks)
    print(results)

asyncio.run(main())

在这里,read_file() 会并发执行,从而节省时间。



六、create_task()gather() 的关系

  • create_task() 是将协程任务注册到事件循环中,让它并发执行。
  • gather() 则是用来收集多个任务的结果,它会等待传入的所有协程完成并返回结果。

你可以结合使用 create_task()gather(),例如:

async def main():
    task1 = asyncio.create_task(job(1))
    task2 = asyncio.create_task(job(2))
    task3 = asyncio.create_task(job(3))

    results = await asyncio.gather(task1, task2, task3)
    print(results)

asyncio.run(main())

这样,你既能够并发执行多个任务,又能收集它们的结果。



七、总结

  • asyncio.create_task(coro) 用于将一个协程任务调度到事件循环中异步执行,立即返回一个 Task 对象。
  • 它允许并发执行多个任务,而不需要等待每个任务完成,可以大大提高 IO 密集型应用的效率。
  • 在需要并发执行多个协程时,create_task() 是非常有用的工具。

希望这些内容能帮助你更好地理解 asyncio.create_task() 的使用!如果你有任何问题,或想看更多的应用示例,随时告诉我!

文章标签:

评论(0)