Відповіді:
Сторінки людини, як правило, є стислими довідковими документами. Вікіпедія - це краще місце для звернення до концептуальних пояснень.
Fork дублює процес: він створює дочірній процес, який майже ідентичний батьківському процесу (найбільш очевидною відмінністю є те, що новий процес має інший ідентифікатор процесу). Зокрема, 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()
батьком буде чекати, коли дитина закінчиться. Батько успадковує змінні, якими обмінюється програма. Тож після виклику дитини всі змінні, модифіковані всередині дитини, все ще будуть модифіковані всередині батьків.
Для отримання додаткової інформації натисніть тут