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
相关产品推荐
相关产品推荐

