2

这是一个很酷的问题。

我有一个调用 python 模块 (foo.py) 的 python 脚本 (main),该模块又调用另一个 python 模块 (barwrapper.py) 使用 LoadLibrary 动态打开和访问 libbar.so 库。

libbar 和整个链的其余部分打开并创建文件来执行它们的任务。当我们在主 python 脚本中发出一个 rmtree 以摆脱导入模块创建的临时目录时,就会出现问题。rmtree 在脚本结束时调用,就在退出之前。调用失败,因为该目录包含.nfs-whatever隐藏文件,我猜这是已删除的文件。这些文件显然在代码中保持打开状态,迫使 nfs 将它们移动到这些.nfs-whatever文件中,直到文件描述符被释放。这种情况在其他文件系统中不会出现,因为与持有的描述符相关联的文件被有效地删除,但内核仍然可以访问,直到描述符关闭。

我们强烈怀疑 .so 库正在泄漏​​文件描述符,而这些未关闭的文件在清理时破坏了 rmtree 聚会。我考虑过在 barwrapper 中卸载 .so 文件,但显然没有办法做到这一点,而且我不确定 dynloader 是否真的会从进程空间中删除 lib 并关闭描述符,或者它是否只会将其标记为已卸载就是这样,等待被其他东西替换,但描述符泄露了。

我真的想不出解决这个问题的其他解决方法(除了修复泄漏,这是我们不想做的事情,因为它是第 3 方库)。显然,它只发生在 nfs 上。你知道我们可以尝试修复它吗?

4

2 回答 2

1

好的解决方案是修复句柄泄漏,但如果您不确定是谁在泄漏,也许strace调用可以帮助您定位泄漏并将错误提交给 3rd 方库的维护人员(或者更好是一个开源库,尝试提交补丁;))。

另一方面,nfs 分区上的 umount/mount 可能有助于强制关闭句柄。

于 2011-05-18T18:39:51.397 回答
1

内核会跟踪文件描述符,因此即使您让 python 卸载 .so 并释放内存,它也不知道关闭泄露的文件描述符。唯一想到的是在分叉后导入 .so ,并且只有在分叉的子进程退出后才进行清理(并且文件句柄在内核退出时隐式关闭)。

于 2011-05-19T00:38:21.713 回答