Python递归深度超限后出现Bad File descriptor错误求助
问题拆解与修复方案
嘿,我来帮你理清这两个错误的根源,重点说说第二个你搞不懂的 [Errno 9] Bad file descriptor [while trying to close foo]:
关于第二个错误的原因
这个错误和daemon.DaemonContext的默认行为直接相关:
- 当你创建
DaemonContext()上下文时,它的默认配置会关闭所有从父进程继承来的文件描述符——这是守护进程的标准设计,目的是让守护进程彻底脱离原进程的资源关联,避免资源泄漏。 - 你的代码里,
with open(...)的文件句柄虽然看起来已经执行完代码块,但Python的with语句是在代码块结束后才去执行文件的close()操作。而你在with块之后立刻启动了DaemonContext,它会抢先关闭这个还没来得及被with语句关闭的文件描述符。等到with语句试图去关闭一个已经被销毁的描述符时,就会抛出"Bad file descriptor"的错误。
再补一句第一个错误(你已经理解,但可以关联下)
你的file_read函数末尾无条件调用了自身,完全没有终止条件,这会导致无限递归,很快就触达Python的递归深度上限,所以会抛出maximum recursion depth exceeded in cmp错误。
代码修复建议
针对这两个问题,你可以这样调整代码:
- 删掉无意义的递归:从你的代码逻辑来看,递归调用
file_read(filename)完全没必要,直接移除这部分代码就能解决递归超限的问题。 - 调整守护进程逻辑的时机:把
DaemonContext的使用放在文件读取完成之后,确保文件句柄已经被with语句正常关闭,避免守护进程误关文件描述符。 - 修正日志方法的笔误:你代码里的
logging.finfo、logging.ferror都是错误写法,正确的是logging.info和logging.error。
修改后的示例代码:
import logging import daemon # 假设read_meta_file和ApacheConfigError已经定义 def file_read(filename): file_content = None # 先完成文件读取,确保文件句柄正常关闭 with open(filename, "r") as file: try: logging.info('loading file %s' % filename) file_content = read_meta_file(file) except (FileNotFoundError, ApacheConfigError) as err: logging.exception(err) # 此时文件已经关闭,再启动守护进程上下文 with daemon.DaemonContext(): # 在这里写入你需要守护进程执行的逻辑,不要留空pass pass return file_content file_read('foo.txt')
内容的提问来源于stack exchange,提问作者Deepanshu Arora
相关产品推荐
相关产品推荐

