当我们在Unix中执行fork时,会继承打开的文件句柄,如果我们不需要使用它们,我们应该关闭它们.但是,当我们使用库时,可能会打开文件句柄,我们无法访问该句柄.我们如何检查这些打开的文件句柄?
在Linux中,您可以检查/proc/
目录 - 对于每个打开的fd,都会有一个名为handle的文件.我几乎可以肯定这种方式是不便携的.
或者你也可以使用lsof
- 适用于Linux,AIX,FreeBSD和NetBSD man lsof
.
如果库是打开你不知道的文件,你怎么知道他们在fork之后不需要它们?未导出的句柄是内部库详细信息,如果库希望它们关闭,它将注册一个atfork()处理程序来关闭它们.在一些代码后面走动,关闭其背后的文件句柄将导致微妙的难以调试的问题,因为当它试图使用它知道它正确打开但未关闭的句柄时,库会意外地出错.
你可以从shell做:
lsof -P -n -p _PID_
其中PID是你的进程的PID.
正如在@Louis Gerbarg的回答中提到的那样,库可能期望文件句柄保持打开状态fork()
(毕竟这应该是父进程的几乎相同的副本).
大多数人的问题exec()
在于经常遵循的问题fork()
.这里,正确的解决方案是创建句柄的库,将它们标记为close-on-exec(FD_CLOEXEC
).
在多线程程序使用的库上,创建文件句柄的库和设置文件句柄之间存在竞争条件FD_CLOEXEC
(fork()
两个操作之间可以有另一个线程).为解决这个问题,O_CLOEXEC
在Linux内核中引入了.