python异步编程案例之事件循环

本文深入探讨了Python中异步编程的概念与实践,详细介绍了如何使用Asyncio库来创建和管理协程,实现并发任务的高效执行。通过具体示例,展示了如何启动协程,如何使用gather和wait函数来并发运行多个协程,以及如何正确地停止和关闭事件循环。

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

先定义一个协程函数

import asyncio

async def do_some_work(x):
    print("Hello:",x)
    return "work is done for {}".format(x)

拿到事件循环对象loop容器,将协程对象扔进事件循环对象中触发。

coroutine = do_some_work('test')
loop = asyncio.get_event_loop()
loop.run_until_complete(coroutine)

run_until_complete 是一个阻塞(blocking)调用,直到协程运行结束,它才返回。

Hello: test

实际项目中,往往有多个协程,同时在一个 loop 里运行。为了把多个协程交给 loop实现并发,需要借助 asyncio.gather 或者 asyncio.wait函数。

coroutines = []
for i in range(5):
    coroutines.append(do_some_work(i))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(coroutines))
# loop.run_until_complete(asyncio.gather(*coroutines))
Hello: 4
Hello: 0
Hello: 1
Hello: 2
Hello: 3

如何停止loop?
需要调用loop.stop(), 利用回调函数实现。

import asyncio
import functools

async def do_some_work(x):
    print("Hello:",x)
    return "work is done for {}".format(x)
    
def done_callback(loop, future):
    loop.stop()
    print("callback: ", future.result())
    
loop = asyncio.new_event_loop() # 创建一个新的loop对象
asyncio.set_event_loop(loop)
futus = asyncio.gather(do_some_work(1), do_some_work(2), do_some_work(3))
futus.add_done_callback(functools.partial(done_callback, loop))
loop.run_forever() #  在调用 stop() 之前将一直运行,restart loop
Hello: 1
Hello: 3
Hello: 2
callback:  ['work is done for 1', 'work is done for 2', 'work is done for 3']

彻底关闭loop
以上示例都没有调用 loop.close,好像也没有什么问题。所以到底要不要调 loop.close 呢?
简单来说,loop 只要不关闭,就还可以再运行。
继续运行以下代码。

loop.run_until_complete(do_some_work(4))
Hello: 4
Out[38]: 'work is done for 4'

但是如果关闭了,就不能再运行其他协程了。

loop.close()
loop.run_until_complete(do_some_work(5))
Traceback (most recent call last):
  File "D:\anaconda3\envs\tensor-flow\lib\site-packages\IPython\core\interactiveshell.py", line 3291, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-41-50fd63fec95a>", line 1, in <module>
    loop.run_until_complete(do_some_work(5))
  File "D:\anaconda3\envs\tensor-flow\lib\asyncio\base_events.py", line 460, in run_until_complete
    self._check_closed()
  File "D:\anaconda3\envs\tensor-flow\lib\asyncio\base_events.py", line 377, in _check_closed
    raise RuntimeError('Event loop is closed')
RuntimeError: Event loop is closed

建议调用 loop.close,以彻底清理 loop 对象防止误用。

<think>我们正在回答用户关于Python异步编程的问题,用户要求了解概念并获取一个简单案例。根据提供的引用内容,我们可以总结:-引用[1]提到异步编程用于处理I/O操作,避免阻塞,实现非阻塞并发执行。-引用[2]指出异步编程提升应用性能和响应性,Python有丰富支持。-引用[3]展示了异步上下文管理器的使用,以及一个简单的异步操作数据库的例子。因此,我们将:1.简要解释异步编程的概念(非阻塞、事件循环、协程)。2.给出一个简单的异步编程案例(例如使用asyncio库执行多个异步任务)。注意:案例需要简单明了,适合理解基本概念。我们将按照以下步骤组织回答:-概念解释-一个简单案例(代码示例)-运行结果说明-案例解析注意:由于引用中提到了异步上下文管理器,但用户要求简单案例,我们选择更基础的案例(例如模拟多个I/O任务并发执行),同时如果合适可以提及异步上下文管理器,但以简单为主。选择案例:使用asyncio.sleep模拟I/O等待,展示异步并发执行。代码结构:1.定义异步函数(使用asyncdef)2.使用asyncio.create_task创建任务,或者直接使用asyncio.gather3.运行事件循环案例:模拟两个需要等待的I/O任务,但实际使用睡眠代替。</think> ### Python异步编程概念与简单案例 #### 异步编程基本概念 异步编程是一种*非阻塞式*编程模型,允许程序在等待I/O操作(如网络请求、文件读写)时继续执行其他任务。核心特点包括: 1. **非阻塞执行**:程序不会因I/O等待而暂停 2. **事件循环(Event Loop)**:驱动异步任务调度 3. **协程(Coroutine)**:使用`async/await`语法定义的异步函数 4. **并发处理**:通过任务切换实现高效并发 #### 简单案例:并发访问多个URL ```python import asyncio import aiohttp async def fetch_url(url): async with aiohttp.ClientSession() as session: # 异步会话管理[^3] async with session.get(url) as response: # 异步HTTP请求 return f"{url}: {response.status}" async def main(): urls = [ "https://www.python.org", "https://www.github.com", "https://www.example.com" ] # 创建并发任务 tasks = [fetch_url(url) for url in urls] # 并发执行所有任务 results = await asyncio.gather(*tasks) # 异步结果收集 for result in results: print(result) # 启动事件循环 asyncio.run(main()) # 运行异步程序[^1] ``` #### 运行结果示例 ``` https://www.python.org: 200 https://www.github.com: 200 https://www.example.com: 200 ``` #### 案例解析 1. **异步I/O**:`aiohttp`发送网络请求时不会阻塞程序 2. **协程定义**:`async def`定义协程,`await`挂起I/O等待 3. **并发模型**:所有请求同时发起(总时间≈最慢的单个请求) 4. **上下文管理**:`async with`确保资源正确释放[^3] 通过这种方式,异步编程能够显著提升I/O密集型应用的性能,传统同步代码可能需要3秒(每个请求1秒),异步版本只需约1秒即可完成所有任务[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值