重启应用程序的简单方法

Simple way to restart application

有些库有一些内存泄漏,作为一个简单的解决方案,我只想经常重启我的脚本。我的脚本做了一些长时间的计算,但我可以保存状态然后再次加载它,所以重新启动它不是问题。

为了重新启动,我只是使用 os.execv:

os.execv(sys.executable, [sys.executable] + sys.argv)

然而,现在过了一段时间,我得到 Too many open files

这是为什么?据我所知,所有文件描述符(fds)应该在 exec 之后关闭?我以为我们总是设置 close-on-exec 标志?但也许不是?或者可能不适用于所有图书馆?也许我误解了文档。有人可以澄清一下吗?

如何关闭 exec 之前的所有 fds? os.closerange?也许只是:

max_fd = os.sysconf("SC_OPEN_MAX")
os.closerange(3, max_fd)
os.execv(sys.executable, [sys.executable] + sys.argv)

这样可以正常工作吗?

还有哪些简单的重启解决方案?我假设 fork+exec+exit 会遇到同样的问题吗?还是生成+退出?

os.execv 本身不会关闭任何文件描述符。 (想一想:如果 exec 系统调用关闭了文件描述符,标准的 fork+exec 模型将无法将标准输入、标准输出和标准错误传递给新进程。) documentation 隐含地提到了这一点,因为它解释了在调用 os.execv.

之前,您需要 flush 任何打开的文件句柄上的任何数据

正如您所描述的,PEP-446 大多数 由 Python 本身创建的文件描述符实现了 close-on-exec。在无法访问您的代码的情况下,我们只能推断您的代码创建的一些文件描述符超出了 PEP 的范围(或由 os.dup2() 创建,您可以在其中控制行为,但默认情况下是使文件描述符可继承)。

您的 os.closerange 代码应该可以满足您的要求。如果你想更精确,check what files are open in Python 有关于如何找出打开了哪些文件的想法(这可能有助于解决根本原因,即使你最终使用 closerange 解决方案来修复眼前的问题)。