You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何await监听被loop.add_reader绑定的fd的关闭事件?

解决方案

你可以通过asyncio.Future作为通知载体,把回调式的文件描述符监听转为可等待的事件,从而替代run_forever()的使用,完整实现代码如下:

import asyncio

myfd = ... # 你的文件描述符,示例中为套接字对象

# 创建Future用于传递fd关闭事件
close_future = asyncio.get_event_loop().create_future()

def reader():
    try:
        data = myfd.recv(100)
        # 套接字返回空字节代表对端已关闭连接
        if not data:
            if not close_future.done():
                close_future.set_result(None)
            # 移除注册的读监听,避免重复触发
            asyncio.get_event_loop().remove_reader(myfd)
            return
        print("Received:", data.decode())
    except Exception as e:
        # 读过程发生异常也视为连接中断,将异常传入Future
        if not close_future.done():
            close_future.set_exception(e)
        asyncio.get_event_loop().remove_reader(myfd)

async def main():
    loop = asyncio.get_running_loop()
    loop.add_reader(myfd, reader)
    # 等待fd关闭事件触发
    await close_future
    # 此处可添加自定义的善后逻辑
    print("myfd已关闭,运行结束")

if __name__ == "__main__":
    asyncio.run(main())

核心逻辑说明

  • Future是asyncio原生支持的可等待对象,我们用它作为回调函数和协程逻辑之间的通信桥:当回调检测到fd关闭时,就将Future标记为完成状态,await该Future的协程就会继续执行。
  • 替换原有run_forever()的无限运行逻辑:使用asyncio.run()启动主协程,主协程会在await close_future处阻塞直到fd关闭,协程执行结束后事件循环会自动退出,不需要手动调用停止方法。
  • 额外注意:原示例代码中asyncio.get_event_loop().loop.add_reader属于冗余写法,get_event_loop()返回的就是事件循环实例,直接调用add_reader方法即可。

内容的提问来源于stack exchange,提问作者user1201614

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 15:45:05