Со страницы руководства vfork()
:
vfork () отличается от fork () тем, что родительский элемент приостанавливается до тех пор, пока дочерний элемент не вызовет execve (2) или _exit (2). Дочерний узел совместно использует всю память со своим родителем, включая стек, до тех пор, пока дочерний объект не выпустит execve (). Дочерний объект не должен возвращаться из текущей функции или вызывать exit (), но может вызывать _exit ().
Почему ребенок должен использовать, _exit()
а не просто звонить exit()
? Я надеюсь, что это применимо к обоим vfork()
и fork()
.
c
system-calls
fork
exit
сен
источник
источник
Ответы:
Как было показано ранее ,
vfork
дочерний процесс не разрешает доступ к памяти родителя.exit
является функцией библиотеки C (вот почему она часто пишется какexit(3)
) Он выполняет различные задачи очистки, такие как очистка и закрытие потоков C (файлы открываются с помощью функций, объявленных вstdio.h
) и выполнение пользовательских функций, зарегистрированных вatexit
. Все эти задачи включают чтение и запись в память процесса._exit
выходит без очистки. Это непосредственно системный вызов (именно поэтому он записан как_exit(2)
), обычно реализуемый путем помещения номера системного вызова в регистр процессора и выполнения определенной инструкции процессора (переход к обработчику системного вызова). Для этого не требуется доступ к памяти процесса, поэтому это безопасно сделать послеvfork
.После
fork
этого такого ограничения нет: родительский и дочерний процессы теперь полностью автономны.источник
init
разветвляется ядром).exit
выполнять дополнительную очистку, например, вызывая функции, зарегистрированные,atexit
следовательно, он получает доступ к данным вне скопированной части._exit
выполняет syscall напрямую, без очистки, кроме как в ядре.источник
У вас есть дочерний вызов _exit (), чтобы избежать очистки буферов stdio (или других) при выходе из дочернего процесса. Поскольку дочерний процесс представляет собой точную копию родительского процесса, дочерний процесс все еще имеет то, что родительский процесс имел в «stdout» или «stderr», буферы из <stdio.h>. Вы можете (и будете в неподходящее время) получать двойные выходные данные, вызывая exit (), один из обработчиков atexit дочернего процесса и один из родительского, когда буферы в родительском процессе заполняются и очищаются.
Я понимаю, что приведенный выше ответ концентрируется на особенностях stdio.h, но эта идея, вероятно, переносится на другие буферизованные операции ввода-вывода, как указывает один из ответов выше.
источник
exit()
: - выполняет некоторую задачу очистки, например, закрывает потоки ввода-вывода и многие другие, а затем возвращает ядро._exit()
: - напрямую попадает в ядро (не выполнять никаких задач по очистке).fork()
: у parent и child есть разные таблицы файлов, поэтому изменения, внесенные потомками, не влияют на параметры среды parent и наоборот.vfork()
: parent и child используют одну и ту же таблицу файлов, поэтому изменение, внесенное child, влияет на параметры среды parent. например, некоторая переменнаяvar=10
, теперь запускаемаяvar++
потомком, а затем запускающая родителя, вы также можете увидеть эффектvar++
в выводе parent.Как я уже говорил , если вы используете
exit()
вvfork()
том всем I / O уже закрыт. Таким образом, даже если родительский элемент работает правильно, вы не можете получить правильный вывод, потому что все переменные сброшены и все потоки закрыты.источник