Прежде всего, немного терминологии .
Исполняемый файл - это простой файл в вашей системе. Процесс - это оболочка, которая выполняет программу, встроенную в исполняемый файл.
Вы правы относительно способа запуска исполняемого файла :
- Родительский процесс (уже живой)
fork
сам по себе, ведущий в двух потоках выполнения с этой точки. Один живет в родительском процессе, а другой - в новом новом процессе. - Новый (дочерний) процесс отключает себя, чтобы выполнить программу исполняемого файла для запуска. Это делается с помощью системного вызова в
exec
семье.
На примере графического интерфейса, в котором вы дважды щелкаете значок исполняемого файла, ваш исполняемый файл разветвляется из процесса, показывая значок, на который вы щелкнули, в основном с этим исходным кодом:
const char *exe_path = taken_from_icon(); int pid = fork(); if(pid == 0) { // I am the new child execl(exe_path, exe_path, NULL); // exec only return in case of failure exit(EXIT_FAILURE); } // I am the graphical interface, // Continue and wait for another clic
Но смерть и родительство ребенка не совсем так, как вы говорите.
В основном - и когда родительский процесс еще жив - дочерний процесс является дочерним по отношению к своему отцу (да! -). У него есть свой PPID (идентификатор родительского процесса), установленный на еще живой процесс, который его разветвил.
Все меняется, когда родительский процесс умирает. Дочерний процесс продолжает жить, но его PPID установлен на еще живущий процесс gran-parent. Всегда есть один, так как init
процесс никогда не умирает.
Тот факт, что дочерние оболочки умирают, когда умирает сама оболочка, является чем-то конкретным. Я вижу две причины для этого:
Первый: оболочка обычно поддерживает список PID, которые она разветвляет. И когда оболочка умирает, она убивает их всех. Основные оболочки имеют
disown
встроенную команду для удаления дочернего элемента из этого списка и оставления его в живых после смерти оболочки. Смотрите страницу руководства bash :Оболочка выходит по умолчанию при получении SIGHUP. Перед выходом интерактивная оболочка отправляет SIGHUP всем работам, запущенным или остановленным. Остановленные задания отправляются SIGCONT, чтобы гарантировать получение SIGHUP. Чтобы командная оболочка не отправляла сигнал на конкретное задание, его следует удалить из таблицы заданий с помощью встроенной команды disown (см. Ниже КОМАНДЫ СОСТАВЛЕНИЯ ОБОЛОЧКИ) или отметить, чтобы она не получала SIGHUP с помощью команды disown -h.
Второй: у дочерних оболочек обычно stdin, stdout и stderr связаны с самой оболочкой через каналы. Если оболочка перестает использовать дочерний стандартный вывод (часто для его печати) или закрывает конец канала, дочерний процесс может иметь ошибки при записи в стандартный вывод, которые могут заблокировать или уничтожить его.