У меня нет большого опыта, я просто пытаюсь участвовать в процессах, как они интерпретируют оборудование на уровне пользователя.
Поэтому, когда команда запускается из оболочки, она fork()
наследует дочерний процесс, exec()
загружает дочерний процесс в память и выполняет.
- Если дочерний процесс содержит все атрибуты родительского процесса (который является исходным процессом), то зачем нужен этот дочерний процесс? Исходный процесс также мог быть загружен в память.
- Относится ли это
fork
иexec
концепция ко всем исполняемым программам в UNIX? Как и для сценария оболочки также или только для команд? Это также относится к встроенным командам оболочки? - Когда используется концепция копирования при записи, если я выполню команду / скрипт?
Извините, что задаю много вопросов одновременно, но все эти вопросы приходят мне на ум сразу, когда я думаю о выполнении любой команды.
Ответы:
Не совсем.
fork()
клонирует текущий процесс, создавая идентичного потомка.exec()
загружает новую программу в текущий процесс, заменяя существующую.Необходимость в том, что родительский процесс еще не хочет завершаться; он хочет, чтобы новый процесс завершился и сделал что-то одновременно с продолжением выполнения.
Для внешних команд оболочка делает
fork()
так, чтобы команда выполнялась в новом процессе. Встроенные команды запускаются непосредственно оболочкой. Еще одна известная командаexec
, которая сообщает оболочкеexec()
внешней программе без предварительногоfork()
вызова. Это означает, что сама оболочка заменена новой программой, и, следовательно, больше не существует этой программы для возврата к ней, когда она завершает работу. Если вы скажете,exec true
то/bin/true
замените вашу оболочку и немедленно выйдете, и в вашем терминале больше ничего не будет работать, поэтому он закроется.Еще в каменном веке
fork()
фактически пришлось скопировать всю память в вызывающем процессе в новый процесс. Копирование при записи - это оптимизация, при которой таблицы страниц настраиваются таким образом, что два процесса начинают совместно использовать одну и ту же память, а при необходимости копируются только те страницы, которые записаны любым процессом.источник
cd
илиread
могут работать. Отсутствие разветвления также делает встроенные функции намного быстрее, чем внешние команды.execve()
наложение себя другим кодом.fork()
иexec()
применимы ко всем исполняемым файлам - фактически, наряду с argc и argv, а pipe, fork и exec - это то, что отличает Unix от других операционных систем. Существует несколько специализаций или обобщенийfork()
, таких как BSDvfork()
, Plan 9rfork()
и Linuxclone()
, но принцип остается тем же.malloc()
или даже статические или глобальные переменные области видимости) могут быть «копировать при записи». Когда дочерний процесс создается сfork()
При вызове ядро настроит дочерний процесс так, чтобы он имел те же самые страницы памяти, что и куча, и стек, как родительский процесс. Если оборудование (модуль управления памятью) обнаруживает запись в кучу или стек, ядро получит новую физическую страницу памяти, скопирует страницу родителя на новую страницу и отобразит эту новую страницу в стеке или куче дочернего процесса. Это представляет собой оптимизацию, поскольку ядро тратит меньше времени на настройку отображений страниц, чем полностью копирует стек и кучу для дочернего процесса.источник
На этот вопрос очень наглядно дан ответ, взглянув на самые ранние реализации Unix, которые должны были работать при жестких ограничениях памяти и иметь только один выполняющийся процесс в памяти / адресном пространстве одновременно.
Многозадачность была достигнута путем помещения процесса на диск и замены другого процесса в.
Теперь
fork
системный вызов был почти таким же: он перенес процесс на диск, но вместо того, чтобы поменять другой процесс, он дал копии в памяти другой идентификатор процесса и вернулся к нему. И это было подходящим моментом для этого процесса, чтобыexec
в конце концов принять решение просто включить другой исполняемый файл.fork
+,exec
таким образом, на самом деле не было заметных накладных расходов на нерест: вы все равно должны были выгружать процесс на диск, и в любом случае старый образ процесса находился в работоспособных местах памяти.С ростом количества доступной памяти и модулей управления памятью и множественных процессов в памяти изначально незначительная стоимость разветвления стала несколько более неприятной для некоторых архитектур: таким образом,
vfork
она и родилась.источник
Чтобы сделать это как можно более понятным, я буду использовать аналогию. Давайте испечь пирог!
Мы берем книгу рецептов, начинаем читать и садимся на клубничный пирог с ревенем (мой любимый) с корочкой ручной работы. Почти все, что нам нужно, находится на кухне, кроме яиц и фруктов, но поскольку мы живем на ферме, а фрукты в сезон, это не проблема. проблема в том, что духовка сломалась, и не хватает времени, чтобы все сделать. Разве не было бы хорошо иметь больше одного из меня?
fork () на помощь. Теперь меня двое. и мы оба идем на кухню, чтобы начать делать корку пирога. упс. Итак, мы смотрим на возврат от форка. Я получил большое число, он получил ноль, поэтому я иду на кухню, а он направляется в курятник и в сад. Проходя мимо духовки, я снова форкаю (), посмотрим на возвращаемое значение: облом я получил ноль. Он продолжает муку, а я смотрю на сломанную духовку. Я открываю дверь, Нет света, я закрываю дверь. Кто-нибудь знает, как починить духовку?
exec () на помощь. Дотягиваясь до вольтметра на ремне с инструментами, лампочка может быть диагностической, поэтому я проверяю мощность, действительно отключенный выключатель, легко исправить. когда я иду к панели выключателя, я вижу парня, который собирает ревень. Тьфу! Я предпочитаю шоколадный шелковый пирог.
источник