Как замечено ранее, vfork
не позволяет дочернему процессу получать доступ к памяти родителя. exit
библиотечная функция C (вот почему, она часто пишется как exit(3)
). Это выполняет различные задачи очистки, такие как сбрасывание и закрытие C потоки (файлы, открытые через функции, объявленные в stdio.h
) и выполнение указанных пользователями функций, зарегистрированных с atexit
. Все эти задачи включают чтение и запись в память процесса.
_exit
выходы без очистки. Это - непосредственно системный вызов (который является, почему это записано как _exit(2)
), обычно реализованный путем размещения числа системного вызова в процессор регистрируются и выполнения конкретной инструкции по процессору (переходящий к обработчику системных вызовов). Это не должно получать доступ к памяти процесса, таким образом, безопасно сделать после vfork
.
После fork
, нет такого ограничения: родительский и дочерний процесс теперь абсолютно автономен.
У Вас есть дочерний вызов _exit (), чтобы не сбрасывать stdio (или другой) буферы, когда дочерний процесс выходит. Так как дочерний процесс составляет точную копию родительского процесса, дочерний процесс все еще имеет то, что родитель имел в "stdout" или "stderr", буферах от <stdio.h>. Вы можете (и быть, в несвоевременные времена) получают двойные выводы путем вызова выхода (), один от atexit обработчиков дочернего процесса, и один от родителя, когда буферы в родительском процессе становятся полными, и сбрасываются.
Я понимаю вышеупомянутые концентраты ответа на stdio.h специфических особенностях, но та идея, вероятно, переносит на другой буферизированный ввод-вывод, как один из ответов выше указывает.
exit
сделайте дополнительную очистку как вызывание функций, зарегистрированных atexit
следовательно это данные доступа вне скопированной части. _exit
выполняет syscall непосредственно w/out любая очистка кроме в ядре.
exit()
:-выполняет некоторую задачу очистки, как закрытие i/o потоков и многих, и затем возвращается к ядру. _exit()
:-непосредственно прибывает в ядро (не выполняйте задачу очистки).
fork()
: у обоих родителей и ребенка есть другая таблица файлов, таким образом, изменение, сделанное ребенком, не влияет на параметры среды родителя, и наоборот.
vfork()
: оба родителя и ребенок используют ту же таблицу файлов, таким образом, изменение, сделанное ребенком, влияет на параметры среды родителя. например, некоторая переменная var=10
, теперь выполненный var++
ребенком и затем выполненным родителем, Вы видите эффект var++
в выводе родителя также.
Как я сказал, используете ли Вы exit()
в vfork()
затем весь i/o уже закрывается. Таким образом, даже если родитель работает правильно, Вы наклоняетесь способный получить надлежащий вывод, потому что все переменные сбрасываются, и все потоки закрываются.
init
разветвлен ядром). – Gilles 'SO- stop being evil' 04.01.2011, 21:16