文件描述符表和系统调用

Posted

技术标签:

【中文标题】文件描述符表和系统调用【英文标题】:File descriptors table and system calls 【发布时间】:2014-05-08 23:23:01 【问题描述】:

我一直在阅读有关文件描述符以及操作系统如何管理文件并为使用 C 系统调用“open()”的进程提供对它们的访问权限的信息,我有几个问题:

文件描述符表:它只是一个所有进程共享的大数据结构(例如,假设有两个进程:进程 A 和进程 B,它们是否有指向操作系统的文件描述符表的指针),还是操作系统为每个进程创建一个全新的文件描述符数组? 还有哪些其他编程语言可以调用系统调用?例如,我知道使用 C/C++ 您可以使用操作系统接口轻松调用系统调用(fork()、close()、open()、execl()... 等等),但是 Java 呢?我不记得有调用这些函数的方法。它在那里究竟是如何工作的? JVM 是否只是将我的代码翻译(需要翻译的内容)到上述系统调用?那么其他高级编程语言(如 Python)呢? 如果我在使用系统调用 close() 打开文件后不关闭文件会有什么危害?

谢谢。

【问题讨论】:

【参考方案1】:

    有一个系统范围的打开文件描述表,还有一个每个进程的打开文件描述符表。每个打开的文件描述符都指向一个打开的文件描述(参见open()close()),但多个描述符可能引用相同的描述(想想dup()dup2()fork())。

    任何语言都可以通过调用适当的汇编程序来调用系统调用,该汇编程序实际上进行系统调用。大多数脚本语言都建立在 C 或 C++ 之上,因此它们不算在内,但其他语言(例如 Fortran 或 Ada 或 D 或 Go)可以以适合其语义的方式提供对系统调用的访问.

    您打开了一个不需要打开的文件描述符,因此您可以同时打开更少的其他文件。如果您的程序很短并且不会耗尽资源,您可以忽略关闭它。关闭文件有助于确保将数据写入磁盘;操作系统内核知道,如果您的程序是打开文件并关闭它的唯一进程,则不再需要它在其缓冲区缓存中的任何磁盘块。

【讨论】:

3.此外,您需要检查 close() 的返回值以获取所有可能错误的通知(尤其是套接字,但文件写入也可能在刷新时失败)。 是的,但请注意 close(fd) 失败的错误语义有点令人困惑。如果close() 失败,fd 是否仍然打开? close() 的 POSIX 描述的第二段说状态未指定。不清楚文件描述符是关闭还是打开,如果打开,是否再次尝试关闭它会以同样的方式失败,等等。这并不是说你不应该注意,特别是如果你的数据很珍贵, 但这并非完全无关紧要。

以上是关于文件描述符表和系统调用的主要内容,如果未能解决你的问题,请参考以下文章

linux系统编程之I/O内核数据结构

Linux 文件描述符

linux 文件IO

全局描述符表GDT

中断描述符表描述符:任务门,中断门,陷阱门(调用门)

系统描述符类型,段描述符类型和段描述符表