asyncio.run asyncio.run_coroutine_threadsafe loop.run_until_complete create_task的区别

本文介绍了Pythonasyncio库中四种关键的协程管理方法:asyncio.run用于主入口点的单线程执行,asyncio.run_coroutine_threadsafe适用于多线程环境,loop.run_until_complete在事件循环中阻塞等待,create_task用于并行任务创建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

asyncio.run, asyncio.run_coroutine_threadsafe, loop.run_until_complete, 和 create_task 是 Python asyncio 中用于管理协程的不同方法,它们在协程的执行和管理方式上有一些区别。

  1. asyncio.run:

    • asyncio.run 是 Python 3.7+ 引入的,用于运行一个协程并等待其完成。
    • 它通常用于应用程序的主入口点,以便在应用程序中方便地运行一个协程。
    • 它创建一个新的事件循环,运行协程,等待协程完成,然后关闭事件循环。

    示例:

    import asyncio
    
    async def main():
        await asyncio.sleep(1)
        print("Hello, world!")
    
    asyncio.run(main())
    
  2. asyncio.run_coroutine_threadsafe:

    • asyncio.run_coroutine_threadsafe 是用于在一个线程中安全地运行协程,并且可以从另一个线程提交协程进行执行。
    • 这在多线程环境下是有用的,可以安全地将协程任务提交给事件循环。
    • 它返回一个 concurrent.futures.Future 对象,您可以使用 .result() 方法来等待协程的结果。
    • asyncio.run_coroutine_threadsafe 函数通常在多线程环境中使用,它会将协程提交到指定的事件循环(在本例中是 loop)中运行,并返回一个 concurrent.futures.Future 对象。在代码中,使用 future.result() 获取协程的结果,但可能因为线程同步的问题导致卡死。

      如果你在单线程环境中使用 asyncio,最简单的方式是使用 asyncio.run 来运行协程

    示例:

    import asyncio
    
    async def my_coroutine():
        await asyncio.sleep(1)
        return "Hello, world!"
    
    async def main():
        future = asyncio.create_task(my_coroutine())
        result = await future
        return result
    
    if __name__ == "__main__":
        result = asyncio.run(main())
        print(result)
    
  3. loop.run_until_complete:

    • loop.run_until_complete 是 asyncio 事件循环对象的方法,用于运行一个协程并等待其完成。
    • 这个方法只能在事件循环的上下文中使用。
    • 它会一直阻塞,直到协程执行完成,然后返回协程的结果。

    示例:

    import asyncio
    
    async def my_coroutine():
        await asyncio.sleep(1)
        return "Hello, world!"
    
    loop = asyncio.get_event_loop()
    result = loop.run_until_complete(my_coroutine())
    print(result)
    
  4. create_task:

    • create_task 是 asyncio 事件循环对象的方法,用于将协程封装为一个任务对象并立即返回任务对象。
    • 任务是协程的包装器,它可以在后台并行执行,而不需要等待其完成。
    • 通常用于同时启动多个协程任务。

    示例:

    import asyncio
    
    async def my_coroutine(task_name, seconds):
        await asyncio.sleep(seconds)
        return f"{task_name} completed after {seconds} seconds"
    
    async def main():
        task1 = asyncio.create_task(my_coroutine("Task 1", 2))
        task2 = asyncio.create_task(my_coroutine("Task 2", 1))
    
        # 此处可以做其他事情,不需要等待任务完成
    
        result1 = await task1
        result2 = await task2
    
        print(result1)
        print(result2)
    
    asyncio.run(main())
    

总结:

  • asyncio.run 用于运行一个协程并等待其完成,通常在应用程序的入口点处使用。
  • asyncio.run_coroutine_threadsafe 用于在多线程环境中安全地运行协程,可以从不同的线程中提交协程进行执行。
  • loop.run_until_complete 用于运行一个协程并等待其完成,通常在事件循环的上下文中使用。
  • create_task 用于创建并行执行的任务,通常在需要同时启动多个协程时使用,然后您可以等待这些任务的完成。
### Python 中的异步处理 #### 使用 `async` 和 `await` Python 提供了原生的支持来编写异步代码,主要依赖于关键字 `async` 和 `await`。当定义一个函数时,在前面加上 `async` 关键字,则该函数会被标记为协程(coroutine),意味着它可以暂停执行并允许其他操作运行[^2]。 ```python import asyncio async def fetch_data(): print("Start fetching") await asyncio.sleep(2) # Simulate IO-bound task with sleep. print("Done fetching") return {'data': 1} ``` 这段代码展示了如何创建一个简单的异步函数,并利用 `await` 来等待另一个耗时的任务完成而不阻塞主线程。 #### 协程调度与事件循环 为了使这些异步函数能够真正并发工作,需要有一个机制去管理和调度它们——即事件循环(event loop)[^1]。默认情况下,每个 Python 进程都有自己的事件循环;可以通过 `asyncio.get_event_loop()` 获取当前环境下的事件循环实例,并调用其 `.run_until_complete()` 方法启动指定的协程直到结束。 ```python loop = asyncio.get_event_loop() result = loop.run_until_complete(fetch_data()) print(result) ``` 对于多线程环境中想要安全地提交任务给特定事件循环的情况,可以借助 `asyncio.run_coroutine_threadsafe()` 函数[^3]: ```python new_loop = asyncio.new_event_loop() # Create a new event loop. def thread_example(message): async def inner(): print(f"Thread example {message}") future = asyncio.run_coroutine_threadsafe(inner(), new_loop) thread_example('from another thread') ``` #### 异步迭代器和支持上下文管理协议的对象 自 Python 3.6 起引入了更加健壮的方式来支持异步生成器以及实现了上下文管理协议(`__aenter__`, `__aexit__`) 的对象,这使得编写复杂的异步逻辑变得更加直观易懂。 ```python class AsyncContextManager: async def __aenter__(self): ... async def __aexit__(self, exc_type, exc_val, exc_tb): ... async def some_function(): async with AsyncContextManager(): # Using an asynchronous context manager. pass ``` 此外,还可以构建基于队列的任务管理系统以优化 I/O 密集型应用的表现,从而提升整体效率和响应能力[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值