execve () и совместное использование файловых дескрипторов - PullRequest
6 голосов
/ 05 июля 2010

Я прочитал с man-страниц execve, что если процесс (A) вызывает execve, то уже открытые файловые дескрипторы копируются в новый процесс (B).

Здесь возникают две возможности: -

1) Означает ли это, что для процесса B создана новая таблица дескрипторов файлов, записи в которую скопированы из более старой таблицы дескрипторов файлов процесса A

2) Либо процесс B получает таблицу дескрипторов файлов процесса A, поскольку после того, как execve процесс A прекратит свое существование, а уже открытые файлы могут быть закрыты только из процесса B, если он получит таблицу дескрипторов файлов процесса A.

Какой из них правильный?

Ответы [ 2 ]

17 голосов
/ 05 июля 2010

execve не создает новый процесс.Он заменяет образ программы вызывающего процесса, пространство памяти и т. Д. Новыми на основе исполняемого файла из файловой системы.Таблица дескрипторов файлов модифицируется путем закрытия любых дескрипторов с установленным флагом close-on-exec;остальные остаются открытыми и находятся в том же состоянии, в котором находились (текущая позиция, блокировки и т. д.) до execve.

Возможно, вы путаете это с тем, что происходит на fork, начиная с execveобычно предшествует fork.Когда процесс разветвляется, у дочернего процесса появляется новая таблица дескрипторов файлов, ссылающаяся на те же описания открытых файлов, что и таблица дескрипторов файлов родительского процесса.

7 голосов
/ 05 июля 2010

Какой из них правильный?

# 2

Хотя вы спрашиваете больше о деталях реализации ОС, и это редко, если вообще важно, для приложений, полностью прозрачноприложениям и зависит от операционной системы.

Обычно говорят, что новый процесс наследует дескрипторы файлов .Кроме тех, у которых установлен флаг FD_CLOEXEC, очевидно.

Даже в случае # 1, если бы мы предположили, что в течение некоторого короткого времени оба процесса A и B находятся в памяти (не совсем, это территория fork ()), копируяиз таблицы FD будет в порядке.Поскольку процесс A будет прерван (exec ()), все его файловые дескрипторы будут близки () d.И это не повлияет на уже скопированные файловые дескрипторы в процессе B. Файловые дескрипторы похожи на указатели на соответствующую структуру ядра, содержащую фактическую информацию о том, на что фактически указывает файловый дескриптор.Копирование таблицы fd не делает копий базовых структур - оно копирует только указатели.Структура ядра содержит счетчик ссылок (необходимый для реализации fork ()), который увеличивается при копировании и, таким образом, знает, сколько процессов его использует.Вызов close () для файлового дескриптора в первую очередь приводит к уменьшению счетчика ссылок.И только если счетчик обнуляется (больше процессов не используют структуру), только тогда ОС фактически закрывает основной файл / сокет / канал / и т.д.(Но, очевидно, даже если внутри ядра два процесса присутствуют в течение некоторого короткого времени одновременно, приложения пользовательского пространства не могут этого увидеть, поскольку новый процесс после exec () также наследует PID исходного процесса.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...