使用Watchdog监听hdf5文件时报OSError[Errno 9]坏文件描述符如何解决
错误根因分析
- Observer重复启动:你定义的
ObserverWrapper类的__init__方法中已经主动调用了self.start()启动了监听线程,但是在main.py调用逻辑里又额外执行了一次self.listener.start(),对同一个Observer实例重复触发启动逻辑,导致底层inotify的文件描述符被异常销毁/重复初始化,触发OSError: [Errno 9] Bad file descriptor报错。 - HDF5文件校验逻辑失效(隐性bug):当前写的重试逻辑没有套入循环结构,文件首次打开报错后只会重试1次就终止,达不到预设的30次重试的效果。
修复方案
1. 解决Bad file descriptor报错
直接删除main.py中重复的self.listener.start()调用即可,修改后代码如下:
self.listener = watchdog_search.ObserverWrapper("/home/path/to/folder") self.on_finished_run(self.listener.wait_for_file())
2. 修复HDF5文件校验重试逻辑(建议同步修改)
调整wait_for_file方法的代码,将打开文件的逻辑放入循环中,确保重试次数生效:
def wait_for_file(self): """ 等待新生成的HDF5文件并校验写入完成 """ max_retry_count = 30 # 最多30秒判断文件是否写入完成 retry_interval_seconds = 1 # 阻塞等待文件创建事件 file_path = self.handler.file_queue.get(block=True) retry_count = 0 while retry_count < max_retry_count: try: file = h5py.File(file_path, "r") except OSError: retry_count += 1 print(f"h5文件 <{file_path}> 仍被占用,重试中 {retry_count}/{max_retry_count}") time.sleep(retry_interval_seconds) except Exception as err: print(f"打开 <{file_path}> 时出现未知错误 <{type(err).__name__}> ") traceback.print_exc() return None else: file.close() return file_path print(f"h5文件 <{file_path}> 达到最大重试次数,跳过处理") return None
额外优化建议
- 原代码中判断文件后缀的逻辑
event.src_path[-3:] == ".hdf5"存在错误,.hdf5后缀长度为5,该判断永远不会命中。建议替换为更稳妥的event.src_path.endswith(".hdf5"),避免漏检HDF5文件。 - 程序退出前主动调用
self.listener.stop()清理Observer线程,避免残留系统资源。
内容的提问来源于stack exchange,提问作者mikanim
相关产品推荐
相关产品推荐

