sleep(событие);

wakeup(событие, приоритет);

Таким образом, в алгоритме wakeup возобновляемому процессу присваивается приоритет. Сравните форму вызова этих алгоритмов с формой вызова события.

ГЛАВА 7. УПРАВЛЕНИЕ ПРОЦЕССАМИ

В предыдущей главе был рассмотрен контекст процесса и описаны алгоритмы для работы с ним; в данной главе речь пойдет об использовании и реализации системных функций, управляющих контекстом процесса. Системная функция fork создает новый процесс, функция exit завершает выполнение процесса, а wait дает возможность родительскому процессу синхронизировать свое продолжение с завершением порожденного процесса. Об асинхронных событиях процессы информируются при помощи сигналов. Поскольку ядро синхронизирует выполнение функций exit и wait при помощи сигналов, описание механизма сигналов предваряет собой рассмотрение функций exit и wait. Системная функция exec дает процессу возможность запускать «новую» программу, накладывая ее адресное пространство на исполняемый образ файла. Системная функция brk позволяет динамически выделять дополнительную память; теми же самыми средствами ядро динамически наращивает стек задачи, выделяя в случае необходимости дополнительное пространство. В заключительной части главы дается краткое описание основных групп операций командного процессора shell и начального процесса init.

На Рисунке 7.1 показана взаимосвязь между системными функциями, рассматриваемыми в данной главе, с одной стороны, и алгоритмами, описанными в предыдущей главе, с другой. Почти во всех функциях используются алгоритмы sleep и wakeup, отсутствующие на рисунке. Функция exec, кроме того, взаимодействует с алгоритмами работы с файловой системой, речь о которых шла в главах 4 и 5.

Системные функции, имеющие дело с управлением памятью Системные функции, связанные с синхронизацией Функции смешанного типа
fork exec brk exit wait signal kill setrgrр setuid
dupreg attachreg detachreg allocreg attachreg growreg loadreg mapreg growreg detachreg

Рисунок 7.1. Системные функции управления процессом и их связь с другими алгоритмами

7.1 СОЗДАНИЕ ПРОЦЕССА

Единственным способом создания пользователем нового процесса в операционной системе UNIX является выполнение системной функции fork. Процесс, вызывающий функцию fork, называется родительским (процесс-родитель), вновь создаваемый процесс называется порожденным (процесс-потомок). Синтаксис вызова функции fork:

pid = fork();

В результате выполнения функции fork пользовательский контекст и того, и другого процессов совпадает во всем, кроме возвращаемого значения переменной pid. Для родительского процесса в pid возвращается идентификатор порожденного процесса, для порожденного — pid имеет нулевое значение. Нулевой процесс, возникающий внутри ядра при загрузке системы, является единственным процессом, не создаваемым с помощью функции fork.

В ходе выполнения функции ядро производит следующую последовательность действий:

1. Отводит место в таблице процессов под новый процесс.

2. Присваивает порождаемому процессу уникальный код идентификации.

3. Делает логическую копию контекста родительского процесса. Поскольку те или иные составляющие процесса, такие как область команд, могут разделяться другими процессами, ядро может иногда вместо копирования области в новый физический участок памяти просто увеличить значение счетчика ссылок на область.

4. Увеличивает значения счетчика числа файлов, связанных с процессом, как в таблице файлов, так и в таблице индексов.

5. Возвращает родительскому процессу код идентификации порожденного процесса, а порожденному процессу — нулевое значение.

Реализацию системной функции fork, пожалуй, нельзя назвать тривиальной, так как порожденный процесс начинает свое выполнение, возникая как бы из воздуха. Алгоритм реализации функции для систем с замещением страниц по запросу и для систем с подкачкой процессов имеет лишь незначительные различия; все изложенное ниже в отношении этого алгоритма касается в первую очередь традиционных систем с подкачкой процессов, но с непременным акцентированием внимания на тех моментах, которые в системах с замещением страниц по запросу реализуются иначе. Кроме того, конечно, предполагается, что в системе имеется свободная оперативная память, достаточная для размещения порожденного процесса. В главе 9 будет отдельно рассмотрен случай, когда для порожденного процесса не хватает памяти, и там же будут даны разъяснения относительно реализации алгоритма fork в системах с замещением страниц.

На Рисунке 7.2 приведен алгоритм создания процесса. Сначала ядро должно удостовериться в том, что для успешного выполнения алгоритма fork есть все необходимые ресурсы. В системе с подкачкой процессов для размещения порождаемого процесса требуется место либо в памяти, либо на диске; в системе с замещением страниц следует выделить память для вспомогательных таблиц (в частности, таблиц страниц). Если свободных ресурсов нет, алгоритм fork завершается неудачно. Ядро ищет место в таблице процессов для конструирования контекста порождаемого процесса и проверяет, не превысил ли пользователь, выполняющий fork, ограничение на максимально-допустимое количество параллельно запущенных процессов. Ядро также подбирает для нового процесса уникальный идентификатор, значение которого превышает на единицу максимальный из существующих идентификаторов. Если предлагаемый идентификатор уже присвоен другому процессу, ядро берет идентификатор, следующий по порядку. Как только будет достигнуто максимально-допустимое значение, отсчет идентификаторов опять начнется с 0. Поскольку большинство процессов имеет короткое время жизни, при переходе к началу отсчета значительная часть идентификаторов оказывается свободной.

На количество одновременно выполняющихся процессов накладывается ограничение (конфигурируемое), отсюда ни один из пользователей не может занимать в таблице процессов слишком много места, мешая тем самым другим пользователям создавать новые процессы. Кроме того, простым пользователям не разрешается создавать процесс, занимающий последнее свободное место в таблице процессов, в противном случае система зашла бы в тупик. Другими словами, поскольку в таблице процессов нет свободного места, то ядро не может гарантировать, что все существующие процессы завершатся естественным образом, поэтому новые процессы создаваться не будут. С другой стороны, суперпользователю нужно дать возможность исполнять столько процессов, сколько ему потребуется, конечно, учитывая размер таблицы процессов, при этом процесс, исполняемый суперпользователем, может занять в таблице и последнее свободное место. Предполагается, что суперпользователь может прибегать к решительным мерам и запускать процесс, побуждающий остальные процессы к завершению, если это вызывается необходимостью (см. раздел 7.2.3, где говорится о системной функции kill).

алгоритм fork

входная информация: отсутствует

выходная информация:

 для родительского процесса — идентификатор (PID) порожденного процесса

 для порожденного процесса — 0

{

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату