Friday, May 18th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Службы ядра Управление заданиями

Управление заданиями

Управление заданиями является возможностью, впервые предоставленной оболочкой С [Joy, 1994], а сегодня предоставляемой большинством оболочек. Оно позволяет пользователю управлять деятельностью групп процессов, называемых заданиями (jobs). Наиболее важными средствами, предоставляемыми управлением заданиями, являются возможности приостанавливать и повторно запускать задания и осуществлять мульти-плексирование доступа к терминалу пользователя. Управление терминалом в одно и то же время предоставляется лишь одному заданию, которое может читать с терминала и записывать в него. Эта возможность предоставляет некоторые преимущества оконных систем, хотя управление заданиями достаточно отличается, чтобы использоваться в комбинации с оконными системами. Управление заданиями реализуется поверх средств групп процессов, сеансов и сигналов.

Каждое задание - это группа процессов. Вне ядра оболочка управляет заданиями, посылая группе процессов задания сигналы с помощью системного вызова killpg, который доставляет сигнал всем процессам в группе. Внутри системы двумя основными пользователями групп процессов являются обработчик терминала и средства межпроцессного взаимодействия. Оба средства записывают идентификаторы групп процессов в своих собственных структурах данных и используют их при доставке сигналов. Кроме того, обработчик сигнала использует группы процессов для мультиплексирования доступа к управляющему терминалу.

Например, специальные символы, набираемые на клавиатуре терминала (например, control-C или control-Y), вызывают отправку сигналов всем процессам в одном задании внутри сеанса; это задание приоритетное (foreground), тогда как все остальные задания в сеансе фоновые (background). Оболочка может изменить фоновое задание, использовав функцию tcsetpgrp(), реализованную ioctl TIOCSPGRP управляющего терминала. Если фоновые задания сделают попытку чтения с терминала, им будет отправлен сигнал SIGTTIN, что обычно приводит к остановке задания. Сигнал SIGTTOU посылается фоновым заданиям при попытке выполнить системный вызов ioctl, который изменил бы состояние терминала, а если для терминала установлена опция TOSTOP, то и при попытке записи в терминал.

Приоритетная группа процессов сеанса хранится в поле tpgrp структуры tty управляющего терминала сеанса. Все другие группы процессов в пределах сеанса фоновые. На рисунке в предыдущей статье лидер сеанса установил в качестве приоритетной группы процессов для своего управляющего терминала свою собственную группу процессов. Таким образом, два его задания находятся в фоновом режиме, а ввод и вывод терминала управляется оболочкой лидера сеанса. Управление заданиями ограничено процессом, который относится к тому же сеансу и терминалу, связанному с данным сеансом. Переназначать управляющий терминал среди групп процессов сеанса разрешается лишь участникам сеанса.

Если управляющий процесс завершается, система отменяет дальнейший доступ к управляющему терминалу и посылает фоновой группе процессов сигнал S1GHUP. Если завершается такой процесс, как управляющая заданиями оболочка, каждая группа процессов, которую эта оболочка создала, становится осиротевшей (orphaned) группой процессов: группой процессов, в которой ни у одного члена нет родителя, который является членом того же сеанса, но другой группы процессов. Таким родителем обычно является управляющая заданиями оболочка, способная возобновить остановленный порожденный процесс. Поле pg_jobc подсчитывает число процессов внутри группы, родителем которых является управляющий процесс. Когда это значение достигает нуля, группа процессов оказывается осиротевшей. Если бы система не предприняла никаких действий, осиротевшие группы процессов, которые были остановлены в то время, когда они стали осиротевшими, вряд ли когда-либо возобновились. Исторически система распоряжалась с такими процессами решительно: они уничтожались. В POSIX и FreeBSD зависшей группе процессов посылаются сигналы зависания и продолжения, если какие-нибудь из ее членов останавливаются, когда она становится осиротевшей из-за завершения родительского процесса. Если процессы перехватывают или игнорируют сигнал зависания, они могут продолжить работу после того, как станут осиротевшими. Система ведет подсчет процессов в каждой группе, у которых родительский процесс находится в другой группе процессов в том же сеансе. Когда процесс завершается, это число настраивается по числу групп всех порожденных процессов. Если число достигает нуля, группа процессов стала осиротевшей. Обратите внимание, что процесс может быть членом осиротевшей группы процессов, даже если его собственный первоначальный родительский процесс по-прежнему действует. Например, если оболочка начинает задание в качестве одного процесса А, затем этот процесс разветвляется с созданием процесса В, а родительская оболочка существует, то процесс В является членом осиротевшей группы процессов, но не является осиротевшим процессом.

Чтобы избежать остановки членов осиротевших групп процессов, когда они пытаются читать или записывать в свой управляющий терминал, ядро не посылает им сигналы SIGTTIN и SIGTTOU и предотвращает их остановку в ответ на эти сигналы. Вместо этого попытки чтения или записи терминала создают ошибку.


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 71 гостей онлайн