Pit*_*kos 19 linux file-descriptors open-files
我正在尝试使用文件描述符获取全貌。假设我有最初具有这些文件描述符的 process1:
_process1_
| |
| 0 stdin |
| 1 stdout |
| 2 stderr |
|__________|
Run Code Online (Sandbox Code Playgroud)
然后我关闭文件描述符 1:
close(1);
Run Code Online (Sandbox Code Playgroud)
文件描述符 1 将(指向)转换为内核的Open Files Table 中的 stdout FILE 结构。
使用上面的代码,文件描述符 1 从进程表中删除,变成:
_process1_
| |
| 0 stdin |
| 2 stderr |
|__________|
Run Code Online (Sandbox Code Playgroud)
但是在内核中发生了什么?stdout
FILE 结构是否被解除分配?如果 stdout 是一个特殊文件(监视器)并且可能被其他进程使用,那怎么可能呢?FILE 结构只是普通文件(例如.txt)呢?如果其他进程正在使用这样的文件怎么办?
Dav*_*rtz 17
文件描述符 1 转换为内核打开文件表中的 stdout FILE 结构。
这是一种误解。内核的文件表与用户空间文件结构没有任何关系。
在任何情况下,内核都有两个间接级别。有代表文件本身的内部结构,它是引用计数。有一个“打开文件描述”是引用计数。然后是文件句柄,它不是引用计数。文件结构指向 inode 本身。打开文件描述包含诸如打开模式和文件指针之类的内容。
当你调用 close 时,你总是关闭文件句柄。当文件句柄关闭时,其打开文件描述的引用计数会减少。如果它变为零,打开的文件描述也会被释放,并且文件本身的引用计数会减少。只有当它变为零时,内核的文件结构才会被释放。
一个进程没有机会释放另一个进程正在使用的资源,因为共享资源是引用计数的。
在这种情况下,不会发生很多事情。stdin、stdout 和 stderr 都倾向于是相同文件描述符的克隆。文件描述符的引用计数器将减一。相同的文件描述符通常由运行程序的 shell 保存,因此需要保留文件描述符。
内核保留所有打开的文件(inode)的引用计数。只要引用计数大于零,文件就会被保留。我希望为打开的文件句柄保留一个单独的计数器。一旦达到零,内核就可以释放文件句柄使用的内存。
当对文件的所有引用(目录条目和文件句柄)都被删除后,文件系统代码将标记 inode 以供重用。文件具有的任何块都可用于分配。很多文件系统会在inode释放时清空inode中的块指针。这使得恢复已删除的文件变得困难。对磁盘的更新可能会被缓冲并在稍后完成。