Справочные страницы обычно являются краткими справочными документами. Википедия - лучшее место для концептуальных объяснений.
Форк дублирует процесс: он создает дочерний процесс, который почти идентичен родительскому процессу (наиболее очевидное отличие состоит в том, что новый процесс имеет другой идентификатор процесса). В частности, fork (концептуально) должен копировать всю память родительского процесса.
Поскольку это довольно дорого, vfork был изобретен для обработки общего особого случая, когда копия не нужна. Часто первое, что делает дочерний процесс, - это загружает новый образ программы, вот что происходит:
if (fork()) {
# parent process …
} else {
# child process (with a new copy of the process memory)
execve("/bin/sh", …); # discard the process memory
}
В execve
загружает вызов новый исполняемый файл программы, и это заменяет код и данные процесса памяти кодом нового исполняемого файла и свежей памяти данных. Таким образом, вся копия памяти, созданная ею, fork
была совершенно даром.
Таким образом, vfork
вызов был изобретен. Это не делает копию памяти. Поэтому vfork
это дешево, но сложно в использовании, так как вы должны быть уверены, что не обращаетесь ни к какому стеку или кучи процесса в дочернем процессе. Обратите внимание, что даже чтение может быть проблемой, потому что родительский процесс продолжает выполняться. Например, этот код не работает (он может работать, а может и не работать, в зависимости от того, получает ли ребенок или родитель первый временной интервал):
if (vfork()) {
# parent process
cmd = NULL; # modify the only copy of cmd
} else {
# child process
execve("/bin/sh", "sh", "-c", cmd, (char*)NULL); # read the only copy of cmd
}
Со времени изобретения vfork были изобретены лучшие оптимизации. В большинстве современных систем, включая Linux, используется форма копирования при записи , при которой страницы в памяти процесса копируются не во время fork
вызова, а позже, когда родительский или дочерний объект впервые записывает страницу. То есть каждая страница начинается как общая и остается общей до тех пор, пока какой-либо процесс не запишет на эту страницу; процесс, который пишет, получает новую физическую страницу (с тем же виртуальным адресом). Копирование при записи делает vfork в основном бесполезным, поскольку fork
в тех случаях, когда vfork
его можно было бы использовать, копирование не производится .
Linux сохраняет vfork. fork
Системный вызов должен еще сделать копию виртуальной таблицы процесса памяти, даже если он не копирует фактическую память; vfork
даже не нужно этого делать. Улучшение производительности незначительно в большинстве приложений.
fork
необходимо создать отдельное отображение виртуальной памяти, чтобы последующие копии при записи влияли только на один из двух процессов.fork()
Иvfork()
системные вызовы различны.fork()
Системный вызов генерирует два идентичных процессы с отдельной памятью.vfork()
Системный вызов генерирует два процесса , которые разделяют ту же память.С
vfork()
родителем будет ждать, пока ребенок кончает. Родитель наследует от переменных, которые разделяет программа. Таким образом, после вызова дочернего элемента все переменные, измененные внутри дочернего элемента, все равно будут изменены внутри родительского элемента.Для получения дополнительной информации нажмите здесь
источник