logo search
Операционные системы

Базовые средства управления процессами в ос Unix

Рассмотрим теперь, что происходит при обращении к системному вызову fork(). При обращении процесса к данному системному вызову операционная система создает копию текущего процесса, т.е. появляется еще один процесс, тело которого полностью идентично исходному процессу. Это означает, что система заносит в таблицу процессов новую запись, тем самым новый процесс получает уникальный идентификатор, а также в системе создается контекст для дочернего процесса.

Новый процесс наследует почти все атрибуты исходного родительского процесса, за исключением идентификационной информации (т.е. у дочернего процесса, в частности, свой идентификатор PID и иной идентификатор родительского процесса). Среди прочего дочерний процесс наследует открытые отцовским процессом файлы. На это свойство в ОС Unix опираются многие механизмы. Хотя необходимо отметить, что наследуются необязательно все открытые файлы: если некоторый файл открывался в специальном режиме, то при формировании дочернего процесса этот файл для него будет автоматически закрыт.

#include <sys/types.h>

#include <unistd.h>

pid_t fork(void);

Соответственно, при успешном завершении сыновнему процессу возвращается значение 0, а родительскому процессу — идентификатор порожденного процесса; в случае ошибки возвращается -1, а в переменной errno будет храниться код ошибки. Поскольку дочерний процесс является копией отцовского процесса, то возникает проблема, как отличить, какой из процессов в данный момент обрабатывается. Анализируя результат, возвращаемый системным вызовом fork(), можно определить, что текущий процесс является предком или потомком.

Рассмотрим пример (Рис. 76.). Пускай в системе обрабатывается процесс с идентификатором 2757. В некоторый момент времени этот процесс обращается к системному вызову fork(), в результате чего в системе появляется новый процесс, который, предположим, имеет идентификатор 2760. Сразу оговоримся, что дочерний процесс может получить совершенно произвольный идентификатор, отличный от нуля и единицы (обычно система выделяет новому процессу первую свободную запись в таблице процессов). По выходу из системного вызова fork() процесс 2757 продолжит свое выполнение с первой команды из then-блока, а дочерний процесс 2760 — с первой команды из else-блока. Далее эти процессы ведут себя независимо с точки зрения системного управления процессами: в частности, порядок их обработки на процессоре в общем случае пользователю неизвестен и зависит от той или иной реализованной в системе стратегии планирования времени процессора.