文件描述符和fork

文件描述符和fork

当子进程被分叉时,它会继承父进程的文件描述符,如果子进程关闭文件描述符会发生什么?如果孩子开始写入,父母端的文件会发生什么?谁来管理这些不一致,内核还是用户?

当进程close通过文件描述符调用关闭特定文件的函数时。在进程的文件表中,引用计数减一。但由于父进程和子进程都持有相同的文件,因此引用计数为 2,关闭后它会减少到 1。由于它不为零,进程仍然继续使用文件,没有任何问题。

请参阅 Terrence Chan UNIX 系统编程(Unix 内核对文件的支持)。

答案1

当子进程被分叉时,它会继承父进程的文件描述符,如果子进程关闭文件描述符会发生什么?

它继承了一个复制文件描述符的。因此,关闭子级中的描述符将为子级关闭它,但不会为父级关闭描述符,反之亦然。

如果孩子开始写入,父母端的文件会发生什么?谁来管理这些不一致,内核还是用户?

它与写入同一个文件的两个进程完全相同(如字面意思所示)。内核独立地调度进程,因此您可能会在文件中获得交错的数据。

然而,POSIX(*nix 系统很大程度上或完全符合),规定C API 中的read()函数write()(映射到系统调用)“当它们在常规文件或符号链接上操作时,彼此之间是原子的 [...]” 。 GNU C手动也暂时关于管道的承诺(请注意默认值PIPE_BUF是 64 kiB,它是附带条件的一部分)。这意味着其他语言/工具的调用,例如使用echoor cat,应该包含在该合同中,因此,如果两个独立的进程尝试同时向同一个管道写入“hello”和“world”,另一个进程会输出什么end 要么是“helloworld”,要么是“worldhello”,而不是“hweolrrlod”之类的东西。

当进程调用 close 函数通过文件描述符关闭特定打开的文件时。进程的文件表将引用计数减一。但是由于父进程和子进程都持有相同的文件(引用计数为 2,关闭后它会减少1)因为它不为零,所以进程仍然继续使用文件,没有任何问题。

有两个进程,父进程和子进程。两者没有共同的“引用计数”。他们是独立的。 WRT 当其中一个关闭文件描述符时会发生什么,请参阅第一个问题的答案。

答案2

每当fork()创建一个新的子进程时,文件描述符根本不会保留 - 它们会被更改。

尽管该文件是重复的,但它将具有不同的文件描述符。

相关内容