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

pyudev异步回调函数无法正常运行,求解决思路

解决pyudev异步回调无法触发的问题

pyudev的MonitorObserver仅支持同步回调函数,直接传入async def定义的协程函数时,pyudev只会创建协程对象但不会执行它,导致回调逻辑失效。解决思路是给异步协程套一个同步包装函数,将协程提交到Python事件循环中执行。

具体实现方案

1. 基础包装实现

先定义你的异步回调协程,再写一个同步包装函数,在包装函数中获取当前运行的事件循环,将协程提交到循环中执行:

import asyncio
import pyudev

# 你的异步回调协程
async def usbDeviceEventHandler(device):
    # 这里写USB设备连接/断开的处理逻辑
    if device.action == 'add':
        print(f"设备已连接: {device}")
    elif device.action == 'remove':
        print(f"设备已断开: {device}")

# 同步包装函数
def sync_callback_wrapper(device):
    # 获取当前运行的事件循环
    loop = asyncio.get_running_loop()
    # 将异步协程提交到事件循环执行
    loop.create_task(usbDeviceEventHandler(device))

# 初始化监控并启动观察者
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='usb')
self.observer = pyudev.MonitorObserver(monitor, sync_callback_wrapper)
self.observer.start()

2. 加入异常处理

为避免协程中未捕获的异常导致程序崩溃,可在包装函数中给任务添加异常处理回调:

def sync_callback_wrapper(device):
    loop = asyncio.get_running_loop()
    task = loop.create_task(usbDeviceEventHandler(device))
    
    # 处理协程执行中的异常
    def handle_task_exception(task):
        try:
            task.result()
        except Exception as e:
            print(f"USB设备回调处理出错: {str(e)}")
    
    task.add_done_callback(handle_task_exception)

注意事项

  • 确保你的程序已经启动了异步事件循环(比如通过asyncio.run(main())启动主协程),否则asyncio.get_running_loop()会抛出异常。
  • 如果你的程序运行在无事件循环的环境中,可考虑在包装函数中用asyncio.run()执行协程,但注意asyncio.run()会阻塞当前线程,需根据场景调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 14:22:10