在C和C++的上下文中,close()
系统调用是内核回收fd并稍后open()
在同一进程生命周期中调用时重用它的唯一方法吗?那么多线程程序呢?
答案1
你的表述是错误的: close 是系统调用(列于系统调用(2)对于Linux)应用程序告诉内核释放资源(而不是相反)。你可以使用跟踪(1)了解某些命令或进程执行的系统调用。也可以看看并行线程(7),凭证(7),叉子(2),执行(2),克隆(2)
是的,文件描述符(和地址空间在虚拟内存, 看映射(2)) 对于给定的所有线程都是通用的过程。但是,您可能(很少)直接使用低级创建“线程”克隆(2)系统调用(实际上仅由实施者像这样的线程库并行线程),在不太可能的情况下,你是不是使用的CLONE_FILES
东西不一样。但直接打电话却clone
是一门黑魔法。
对于 pid 1234 的给定进程,在 Linux 上,您可以查询文件描述符集(在过程(5))通过/proc/1234/fd/
和内存映射通过/proc/1234/maps
(等等等等...有很多有用的伪中的文件和链接/proc/1234
)。从流程内部,您可以使用/proc/self/fd/
- 例如 作为参数打开目录(3)
当然,文件描述符不仅仅是一个POSIX或 Linux 的东西比标准C99或者C++11一。例如,文件号(3)&打开是在 POSIX 中定义的,而不是在 C99 中定义的。
因此,如果您看到给定的数字 - 例如 49 - 被open
多次返回,那是因为程序的其他部分(可能在某个库内,在另一个线程中)调用了close
49。内核永远不会“神奇地”关闭文件描述符(进程终止时除外)无需询问。您可以使用调试器strace
或gdb
在调试器上设置断点(可能是条件断点)close
答案2
除此之外,还有一些系统调用close
可能会导致文件描述符被关闭和重用:dup2
并且,在 Linux 上,dup3
.
您可能还想检查跟踪日志中的这些内容。