b8c4c21f

Запуск дочерних процессов в Linux

Запуск одного процесса вместо другого организован в Linux с помощью системного вызова exec(). Старый процесс из памяти удаляется навсегда, вместо него загружается новый, при этом настройка окружения не меняется, даже PID остается прежним. Вернуться к выполнению старого процесса невозможно, разве что запустить его снова с помощью того же exec() (от "execute" – "исполнить"). Кстати, имя файла (программы), из которого запускается процесс, и собственное имя процесса (в таблице процессов) могут и не совпадать. Собственное имя процесса – это такой же параметр командной строки, как и те, что передаются ему пользователем: для exec() требуется и путь к файлу, и полная командная строка, нулевой (стартовый) элемент которой – как раз название команды1).
Вот откуда "-" в начале имени стартового командного интерпретатора (-bash): его "подсунула" программа login, чтобы была возможность отличать его от других запущенных тем же пользователем оболочек.
Для работы командного интерпретатора одного exec() недостаточно. В самом деле, shell не просто запускает утилиту, а дожидается ее завершения, обрабатывает результаты ее работы и продолжает диалог с пользователем. Для этого в Linux служит системный вызов fork() ("вилка, развилка"), применение которого приводит к возникновению еще одного, дочернего, процесса – точной копии породившего его родительского. Дочерний процесс ничем не отличается от родительского: имеет такое же окружение, те же стандартный ввод и стандартный вывод, одинаковое содержимое памяти и продолжает работу с той же самой точки (возврат из fork()). Отличий два: во-первых, эти процессы имеют разные PID, под которыми они зарегистрированы в таблице процессов, а во-вторых, различается возвращаемое значение fork(): родительский процесс получает в качестве результата fork() идентификатор процесса-потомка, а процесс-потомок получает "0".
Дальнейшие действия shell при запуске какой-либо программы очевидны. Shell-потомок немедленно вызывает эту программу с помощью exec(), а shell-родитель дожидается завершения работы процесса-потомка (PID которого ему известен) с помощью еще одного системного вызова, wait(). Дождавшись и проанализировав результат команды, shell продолжает работу:
[methody@localhost methody]$ cat > loop while true; do true; done ^D [methody@localhost methody]$ sh loop ^C [methody@localhost methody]$

Запуск дочерних процессов
Права доступа в файловой системе
Ввод и вывод
Редактирование ввода