Где начинается дочерний процесс после вызова fork ()? - PullRequest
0 голосов
/ 05 июля 2018

В соответствии с книгой «Расширенное программирование в среде UNIX», после того, как мы вызываем fork(), вызов дочернего процесса exec() запускает новый процесс. exec() будет использовать новый процесс для замены старого, а новый будет начинаться с main(). Но мы все знаем, что когда мы вызываем fork(), и родительский, и дочерний процессы начинаются с функции fork(). Итак, как мы понимаем мнение книги?

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

Возможно, у них была некоторая путаница в формулировке книги:

• Мы вызываем fork для создания нового процесса, который является копией вызывающей стороны. Мы говорим, что вызывающий является родителем, и что недавно созданный Процесс - это ребенок. Затем fork возвращает неотрицательный идентификатор процесса новый дочерний процесс к родителю и возвращает 0 дочернему процессу. Поскольку fork создает новый процесс, мы говорим, что он вызывается один раз - родитель - но возвращается дважды - у родителя и у ребенка.

• В дочернем процессе мы вызываем execlp для выполнения прочитанной команды. со стандартного ввода. Это заменяет дочерний процесс новым файл программы. Комбинация fork, сопровождаемая exec, называется порождает новый процесс в некоторых операционных системах. В системе UNIX две части разделены на отдельные функции. Мы много скажем Подробнее об этих функциях см. в главе 8.

При успешном вызове fork() мы возвращаемся дважды. Один раз как родительский процесс, и снова как child .

Вызов exec() изменит программу, в которой выполняется процесс. Это часто связывается с дочерним процессом после вызова fork(), но это совершенно необязательно.

Для простоты fork() создает (дублирует) процессы, а exec() изменяет наши процессы.

fork (2) man page

exec (3) man page

0 голосов
/ 05 июля 2018

fork() создает дочерний процесс, дублируя вызывающий процесс. Процесс, который вызвал fork(), является родительским процессом , а недавно созданный процесс является дочерним процессом . Таким образом, fork() разделяет процесс на две части и возвращает 0 дочернему процессу и PID дочернего процесса родительскому процессу, или -1, если не удалось получить ответвление.

Дочерний и родительский процессы выполняются в разных пространствах памяти. Во время fork() оба пространства памяти имеют одинаковое содержимое.

Когда вы вызываете exec() из процесса, он запускает исполняемый файл в контексте уже существующего процесса, заменяя предыдущий исполняемый файл. Новая программа загружается в то же адресное пространство процесса. Текущий процесс просто превращен в новый процесс и, следовательно, PID не изменился, это потому, что мы не создаем новый процесс, мы просто заменяем процесс другим процессом в exec.

Существует концепция, называемая Copy-on-Write, хорошо знать об этом -

Копирование при записи - это оптимизация, при которой таблицы страниц настраиваются так, что родительский и дочерний процессы начинают совместно использовать одну и ту же память, и при необходимости копируются только те страницы, которые записаны любым процессом.

Если процесс не изменяет какую-либо память и немедленно выполняет новый процесс, полностью заменяя адресное пространство. Таким образом, было бы расточительно копировать всю память процесса во время разветвления, и вместо этого используется метод копирования при записи.

0 голосов
/ 05 июля 2018

Полагаю, это также может повлиять на ответ: может быть некоторая путаница. Новый процесс появляется с помощью fork (). exec () заменяет запускаемую программу ... но не создает и не запускает новый процесс. Я подозреваю, что термин процесс может использоваться немного свободно? Вы также можете обратиться к справочной странице execve(2) для уточнения номенклатуры и объяснения:

execve() выполняет программу, указанную filename. Это приводит к тому, что программа, которая в данный момент выполняется вызывающим процессом, заменяется новой программой с вновь инициализированными сегментами стека, кучи и (инициализированными и неинициализированными) данных.

...