Ваш первый вопрос —
what being in the child/father process technically means
fork()
создает дочерний процесс, дублируя вызывающий процесс. Процесс, вызвавший fork()
, является родительским процессом, а вновь созданный процесс является дочерним процессом. Таким образом, fork()
делит процесс на два и возвращает 0 дочернему процессу и PID дочернего процесса родительскому процессу или -1, если вилка не удалась.
Дочерний процесс и родительский процесс выполняются в разных областях памяти. Во время fork() оба пространства памяти имеют одинаковое содержимое.
Существует концепция под названием Копирование при записи, полезно знать об этом.
Копирование при записи — это оптимизация, при которой таблицы страниц настраиваются таким образом, что родительский и дочерний процессы начинают совместно использовать всю одну и ту же память, и при необходимости копируются только те страницы, которые записываются любым процессом.
Если процесс не изменяет память и сразу же запускает новый процесс, полностью заменяя адресное пространство. Таким образом, было бы расточительно копировать всю память процесса во время разветвления, и вместо этого используется метод копирования при записи.
Например, в вашей программе сразу после fork
вызывается execlp
:
if(fork()==0){
//processus fils
//executer la commande
execlp(ligne, ligne, NULL);
Ваш второй вопрос —
I couldn't see the use of waitpid, what will happen if I didn't use it?
Чтобы объяснить это, я изменил вашу программу и добавил оператор для печати pid родительского и дочернего процесса и прокомментировал этот оператор:
waitpid(-1,NULL,0);
Вывод программы -
parent process pid : 22325
-->ls
child process pid : 22326
< here the output of ls command >
Теперь, если мы увидим вывод команды ps
с идентификатором родительского процесса grep -
# ps -eaf | grep 22325
root 22325 21555 0 10:39 pts/4 00:00:00 ./a.out
root 22326 22325 0 10:39 pts/4 00:00:00 [ls] <defunct>
root 22339 21644 0 10:39 pts/5 00:00:00 grep 22325
Здесь в выводе первый столбец — это UID, второй — PID, а третий — PPID (родительский pid). Вы можете видеть, что дочерний процесс (pid - 22326) помечен как ‹ несуществующий >.
"Несуществующий" процесс (также называемый "зомби-процессом") – это процесс, который завершил выполнение и будет иметь статус выхода. сообщить своему родительскому процессу. Из-за этой последней небольшой информации процесс останется в таблице процессов операционной системы как процесс-зомби, что указывает на то, что его дальнейшее выполнение не планируется, но что он не может быть полностью удален (и его идентификатор процесса не может быть удален). повторно используется) до тех пор, пока не будет определено, что статус выхода больше не нужен.
А вот и использование waitpid()
-
Функции wait()
и waitpid()
должны получать информацию о состоянии, относящуюся к одному из дочерних процессов вызывающей стороны.
waitpid()
приостанавливает вызывающий процесс до тех пор, пока система не получит информацию о состоянии дочернего процесса. Если в системе уже есть информация о состоянии соответствующего дочернего элемента, когда вызывается waitpid()
, waitpid()
возвращается немедленно. waitpid()
также завершается, если вызывающий процесс получает сигнал, действие которого заключается либо в выполнении обработчика сигнала, либо в завершении процесса.
Для получения других сведений о waitpid()
, таких как синтаксис (статус, параметры) и возвращаемое значение, вы можете проверить его man а> страница.
Если я раскомментирую waitpid()
в вашей программе, скомпилирую и запущу ее, вывод -
parent process id : 23069
-->ls
child process id : 23070
<here the output of ls command>
Теперь, если мы увидим вывод команды ps с идентификатором родительского процесса grep -
# ps -eaf | grep 23069
root 23069 21555 0 10:51 pts/4 00:00:00 ./a.out
root 23108 21644 0 10:51 pts/5 00:00:00 grep 23069
Процесса зомби нет. Дочерний процесс, выполняющий команду ls
, был завершен, и родительский процесс прочитал свой статус выхода.
Надеюсь, это ответит на ваши оба вопроса.
person
H.S.
schedule
14.10.2017