[Я повторю частину своєї відповіді звідси .]
Чому б просто не мати команду, яка створює новий процес з нуля? Хіба не абсурдно і неефективно скопіювати той, який буде замінений лише одразу?
Насправді це може бути не настільки ефективним з кількох причин:
«Копія» проводиться fork()
трохи абстракції, так як ядро використовує копіювання при записі системи ; все, що дійсно має бути створене - це карта віртуальної пам'яті. Якщо копія негайно викликає виклик exec()
, більшість даних, які були б скопійовані, якби вони були змінені діяльністю процесу, ніколи насправді не потрібно копіювати / створювати, оскільки процес не робить нічого, що вимагає його використання.
Різні суттєві аспекти дочірнього процесу (наприклад, його оточення) не потрібно індивідуально дублювати або встановлювати на основі складного аналізу контексту тощо. Вони просто вважаються такими ж, як і в процесі виклику, і це досить інтуїтивна система, з якою ми знайомі.
Щоб пояснити №1 трохи далі, пам'ять, яка "копіюється", але згодом до неї ніколи не дійсно копіюється, принаймні в більшості випадків. Виняток у цьому контексті може бути, якщо ви розблокували процес, а потім вийшов з батьківського процесу до того, як дитина замінила себе exec()
. Я говорю міць , тому що велика частина батьків може бути в кеші , якщо є достатньо вільного місця, і я не впевнений , якою мірою це буде експлуатуватися (що буде залежати від реалізації ОС).
Звичайно, це не дозволяє зробити копію більш ефективною, ніж використання порожнього шиферу, - окрім "порожнього шиферу" - це не буквально нічого, і він повинен передбачати розподіл. У системі може бути загальний шаблон пустого / нового процесу, який він копіює так само, 1, але це насправді нічого не збереже, порівняно з виделкою копіювання при записі. Тож №1 просто демонструє, що використання "нового" порожнього процесу не було б більш ефективним.
Точка №2 пояснює, чому використання вилки, ймовірно, більш ефективно. Навколишнє середовище дитини успадковується від свого батька, навіть якщо це абсолютно інший виконуваний файл. Наприклад, якщо батьківський процес є оболонкою, а дочірній веб-браузер, $HOME
все ще однаковий для обох, але оскільки обидва згодом могли його змінити, це повинні бути дві окремі копії. Той у дитини виробляється оригіналом fork()
.
1. Стратегія, яка може не мати особливого буквального сенсу, але я можу сказати, що створення процесу передбачає більше, ніж копіювання його зображення в пам'ять з диска.