2010-07-05 4 views
4

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

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

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

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

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

ответ

5

Какой именно?

# 2

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

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

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

12

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

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

+1

Я думаю, что это серьезное ограничение здесь @ stackoverflow.com, хотя оба ответа верны, но я могу отметить только один из них как зеленый. – Ashish

Смежные вопросы