【发布时间】:2018-05-10 16:40:29
【问题描述】:
我有一个疑问: 当我创建一个带有 fd = open() 的文件描述符或带有 fd = socket() 的套接字时,我将它传递给一个函数 function( fd) 即 close(fd),在 main 函数中,fd 仍然可用还是不起作用? 换句话说,当我关闭按值传递给函数的文件描述符时,它是否也为调用函数关闭?
【问题讨论】:
我有一个疑问: 当我创建一个带有 fd = open() 的文件描述符或带有 fd = socket() 的套接字时,我将它传递给一个函数 function( fd) 即 close(fd),在 main 函数中,fd 仍然可用还是不起作用? 换句话说,当我关闭按值传递给函数的文件描述符时,它是否也为调用函数关闭?
【问题讨论】:
是的,file descriptor(在 Unix 系统上,POSIX 系统上,...)对于内核和您当前的整个进程都是已知的。每个process都有自己的文件描述符表和virtual address space。
在 Linux 上,您可以使用proc(5) 来查询文件描述符和某个进程的虚拟地址空间。对于pid 1234的进程,使用/proc/1234/fd/&/proc/1234/fdinfo/了解其文件描述符及其表,/proc/1234/maps&/proc/1234/smaps了解其虚拟地址空间。
所以如果一个被调用的函数close-s 它,你不应该再使用它了。当然,您可以重新激活它(与其他一些 open、socket、dup 一起返回它)。
因此,您需要定义、记录和明确约定close-ing 职责(就像您对free-ing 指针所做的那样)。另请阅读RAII。
在这方面,close 有点像free:它使传递给它的值(close 的文件描述符,free 的指针)。如果可能,您可以在成功的close(2) 之后将文件描述符设置为-1(或其他一些无效值),例如代码close(fd); fd = -1;。出于类似的原因,我也会尽可能free(ptr), ptr = NULL;。
顺便说一句,我假设是 Unix 或 POSIX(或 Linux)系统。我不了解 Windows,它的文件描述符和 sockets 的概念非常不同。
【讨论】:
close() 一个套接字。你必须使用closesocket()。见stackoverflow.com/questions/35441815/… 和msdn.microsoft.com/en-us/library/windows/desktop/…
我建议您阅读有关 close() 系统调用的一些文档,但是无论进程中的“位置”如何,调用 close() 都会导致内核陷入陷阱并删除进程对 fd 的访问。它不一定会释放任何资产。
【讨论】: