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