当子进程被分叉时,它会继承父进程的文件描述符,如果子进程关闭文件描述符会发生什么?如果孩子开始写入,父母端的文件会发生什么?谁来管理这些不一致,内核还是用户?
当进程close
通过文件描述符调用关闭特定文件的函数时。在进程的文件表中,引用计数减一。但由于父进程和子进程都持有相同的文件,因此引用计数为 2,关闭后它会减少到 1。由于它不为零,进程仍然继续使用文件,没有任何问题。
请参阅 Terrence Chan UNIX 系统编程(Unix 内核对文件的支持)。
答案1
当子进程被分叉时,它会继承父进程的文件描述符,如果子进程关闭文件描述符会发生什么?
它继承了一个复制文件描述符的。因此,关闭子级中的描述符将为子级关闭它,但不会为父级关闭描述符,反之亦然。
如果孩子开始写入,父母端的文件会发生什么?谁来管理这些不一致,内核还是用户?
它与写入同一个文件的两个进程完全相同(如字面意思所示)。内核独立地调度进程,因此您可能会在文件中获得交错的数据。
然而,POSIX(*nix 系统很大程度上或完全符合),规定C API 中的read()
函数write()
(映射到系统调用)“当它们在常规文件或符号链接上操作时,彼此之间是原子的 [...]” 。 GNU C手动也暂时关于管道的承诺(请注意默认值PIPE_BUF
是 64 kiB,它是附带条件的一部分)。这意味着其他语言/工具的调用,例如使用echo
or cat
,应该包含在该合同中,因此,如果两个独立的进程尝试同时向同一个管道写入“hello”和“world”,另一个进程会输出什么end 要么是“helloworld”,要么是“worldhello”,而不是“hweolrrlod”之类的东西。
当进程调用 close 函数通过文件描述符关闭特定打开的文件时。进程的文件表将引用计数减一。但是由于父进程和子进程都持有相同的文件(引用计数为 2,关闭后它会减少1)因为它不为零,所以进程仍然继续使用文件,没有任何问题。
有两个进程,父进程和子进程。两者没有共同的“引用计数”。他们是独立的。 WRT 当其中一个关闭文件描述符时会发生什么,请参阅第一个问题的答案。
答案2
每当fork()
创建一个新的子进程时,文件描述符根本不会保留 - 它们会被更改。
尽管该文件是重复的,但它将具有不同的文件描述符。