Файловый дескриптор и форк

15

Когда дочерний элемент разветвляется, он наследует файловые дескрипторы родителя. Если дочерний элемент закрывает файловый дескриптор, что произойдет? Если ребенок начинает писать, что произойдет с файлом в конце родительского? Кто управляет этими несоответствиями, ядро ​​или пользователь?

когда процесс вызывает closeфункцию для закрытия определенного открытого файла через дескриптор файла. В таблице файлов процесса счетчик ссылок уменьшается на единицу. Но так как parent и child содержат один и тот же файл, счетчик ссылок равен 2, а после закрытия он уменьшается до 1. Поскольку он не равен нулю, процесс по-прежнему продолжает использовать файл без каких-либо проблем.

См. Системное программирование Терренса Чана в UNIX, (Поддержка файлов в ядре Unix).

Мадан Рам
источник
Хорошо, не возражает , что последний комментарий;) в человеке страницах open()и fork()есть различие между файлом дескриптами-или и в файл descipt-ионе - бывший относится к позже, и хотя дескрипторы в вилке копия, они ссылаются на одно и то же описание. Тем не менее, при проверке становится очевидным, что это не означает, что закрытие ручки ребенка закрывает ручку родителей. Я думаю, что это может иметь незначительное значение для чередования данных, когда пишут оба дескриптора, но это в любом случае не определено, поэтому, как именно это происходит, не так важно.
Златовласка

Ответы:

29

Когда дочерний элемент разветвляется, он наследует файловые дескрипторы родителя. Если дочерний элемент закрывает файловый дескриптор, что произойдет?

Он наследует копию дескриптора файла. Таким образом, закрытие дескриптора в дочернем элементе закроет его для дочернего элемента, но не для родительского, и наоборот.

Если ребенок начинает писать, что произойдет с файлом в конце родительского? Кто управляет этими несоответствиями, ядро ​​или пользователь?

Это точно (как в буквальном смысле) так же, как два процесса, записывающие в один и тот же файл. Ядро планирует процессы независимо, поэтому вы, скорее всего, получите чередующиеся данные в файле.

Однако POSIX (которому системы * nix в основном или полностью соответствуют) предусматривает, что функции read()и write()функции из C API (которые сопоставляются с системными вызовами) являются «атомарными по отношению друг к другу [...], когда они работают с обычными файлами или символические ссылки ". GNU C вручную также временно обещает это в отношении каналов (обратите внимание, что значение по умолчанию PIPE_BUF, которое является частью условия, составляет 64 КБ). Это означает, что вызовы на других языках / инструментах, таких как использование echoили cat, должны быть включены в этот контракт, поэтому, если два независимых процесса попытаются записать «привет» и «мир» одновременно в один и тот же канал, что получится в другом конец это либо "helloworld" или "worldhello", и никогда что-то вроде "

когда процесс вызывает функцию закрытия, чтобы закрыть определенный открытый файл с помощью файлового дескриптора. Таблица файлов процесса уменьшает счетчик ссылок на единицу. Но поскольку родительский и дочерний элементы содержат один и тот же файл (в этом случае счетчик ссылок равен 2, а после закрытия он уменьшается 1) поскольку он не равен нулю, процесс все равно продолжает использовать файл без каких-либо проблем.

Есть два процесса, родитель и ребенок. У них нет общего количества ссылок. Они независимы. WRT, что происходит, когда один из них закрывает дескриптор файла, см. Ответ на первый вопрос.

лютик золотистый
источник
1

Всякий раз, когда fork()создается новый дочерний элемент, дескрипторы файлов не сохраняются вообще - они изменяются.

Хотя файл будет дубликатом, он будет иметь другой дескриптор файла.

mannukaushikece
источник