Кто разветвляется, когда приложения дважды щелкают по Linux?

Таким образом, я знаю, когда в shell и я запускаю исполняемый файл, тогда shell разветвляет его в дочерний процесс, а затем exec для получения программы и памяти данных моего исполняемого файла. Так что, если моя оболочка теперь закрыта / закрыта, то все связанные с ней дочерние процессы также будут уничтожены.

Я читал, что в Linux каждый процесс создается с помощью fork() exec(). Мне любопытно, и мне было интересно, когда приложение запускается двойным щелчком по его значку, какой процесс forks() exec(), я понимаю, что это какой-то процесс ОС, мне было интересно, какой

Спасибо!

Ответ проследил это до /sbin/upstart

1 ответ

Решение

Прежде всего, немного терминологии.

Исполняемый файл - это простой файл в вашей системе. Процесс - это оболочка, которая выполняет программу, встроенную в исполняемый файл.


Вы правы относительно способа запуска исполняемого файла:

  1. Родительский процесс (уже живой) fork Сам, ведущий в двух потоках выполнения с этой точки. Один живет в родительском процессе, а другой - в новом новом процессе.
  2. Новый (дочерний) процесс отключается, чтобы запустить программу исполняемого файла. Это делается с помощью системного вызова 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 связаны с самой оболочкой через каналы. Если оболочка перестает использовать дочерний стандартный вывод (часто для его печати) или закрывает конец канала, дочерний процесс может иметь ошибки при записи в стандартный вывод, которые могут заблокировать или уничтожить его.

Другие вопросы по тегам