如何(从内部)找到进程中的所有打开文件?
fork()
在(之前)之后知道这似乎很有用exec()
。
我知道 的存在getdtablesize()
并且更便携,但是尝试关闭每个有效sysconf(_SC_OPEN_MAX)
的文件描述符似乎效率低下,无论后面是否有打开的文件。(我也意识到过早优化的危险,我猜这更多是关于美学:-)
如何(从内部)找到进程中的所有打开文件?
fork()
在(之前)之后知道这似乎很有用exec()
。
我知道 的存在getdtablesize()
并且更便携,但是尝试关闭每个有效sysconf(_SC_OPEN_MAX)
的文件描述符似乎效率低下,无论后面是否有打开的文件。(我也意识到过早优化的危险,我猜这更多是关于美学:-)
如果您的程序将调用fork
and exec
,您确实应该使用该标志打开所有文件描述符,O_CLOEXEC
这样您就不必在之前手动关闭它们exec
。您也可以fcntl
在打开文件后使用添加此标志,但这取决于多线程程序中的竞争条件。
尝试关闭所有文件描述符可能听起来效率低下,但实际上并没有那么糟糕。如果系统好的话,查找文件描述符的系统调用实现应该是相当有效的。
如果你只想找到关闭打开的文件描述符,你可以在它存在的系统上使用 proc 文件系统。例如在 Linux 上,/proc/self/fd 将列出所有打开的文件描述符。迭代该目录,并关闭所有>2,不包括表示您正在迭代的目录的文件描述符。
在支持它的系统上(基本上意味着除 Linux 之外的任何 unix),有 closefrom(2) 系统调用,专门为此目的设计的。
刚刚花了很多时间追踪一个错误,是的,关闭所有文件描述符可能会导致问题。
问题是,有多少个文件描述符?
1024 曾经很常见,而 1024 并不是一个完全不合理的要关闭的文件句柄数。由于它们中的大多数都已关闭,因此这只是检查内存中的一个字节。
我的操作系统出厂默认值为 1,048,576。在这个(诚然很慢)服务器上,尝试关闭文件句柄显然可能需要超过 4.7 微秒。这导致超时(5 秒)。并且不知道这个数字会增长多高。至少给它一个(合理的)上限。
/proc/self/fd 并不理想,但这样的错误很难找到。