Операционная система UNIX - страница 77

стр.

, который может принимать следующие значения:

>SIG_BLOCKРезультирующая маска получится путем объединения текущей маски и набора >set
>SIG_UNBLOCKСигналы набора >set будут удалены из текущей маски
>SIG_SETMASKТекущая маска будет заменена на набор >set

Если указатель >set равен >NULL, то аргумент how игнорируется. Если аргумент >oset не равен >NULL, то в набор, адресованный этим аргументом, помещается текущая маска сигналов.

Функция sigpending(2) используется для получения набора заблокированных сигналов, ожидающих доставки:

>#include


>int sigpending(int how, sigset_t *set, sigset_t *oset);

Список сигналов, ожидающих доставки, возвращается в наборе, адресованном аргументом >set.

Системный вызов sigsuspend(2) замещает текущую маску набором, адресованным аргументом >set, и приостанавливает выполнение процесса до получения сигналов, диспозиция которых установлена либо на завершение выполнения процесса, либо на вызов функции-обработчика сигнала.

>#include


>int sigsuspend(const sigset_t *set);

При получении сигнала, завершающего выполнение процесса, возврата из функции sigsuspend(2) не происходит. Если же диспозиция полученного сигнала установлена на вызов функции-обработчика, возврат из sisuspend(2) происходит сразу после завершения обработки сигнала. При этом восстанавливается маска, существовавшая до вызова sigsuspend(2).

Заметим, что в BSD UNIX вызов signal(3) является упрощенным интерфейсом к более общей функции sigaction(2), в то время как в ветви System V signal(3) подразумевает использование старой семантики ненадежных сигналов.

В заключение для иллюстрации изложенных соображений, приведем версию функции signal(), позволяющую использовать надежные сигналы. Похожая реализация используется в BSD UNIX. С помощью этой "надежной" версии мы повторим пример, рассмотренный нами выше, в измененном виде.

>#include

>#include

>#include

>#include

>#include


>/* Вариант "надежной" функции signal() */

>void (*mysignal(int signo, void (*hndlr)(int)))(int) {

> struct sigaction act, oact;

> /* Установим маску сигналов */

> act.sa_handler = hndlr;

> sigemptyset(&act.sa_mask);

> act.sa_flags = 0;

> if (signo != SIGALRM)

>  act.sa_flags = SA_RESTART;

> /* Установим диспозицию */

> if (sigaction(signo, &act, &oact) < 0)

>  return SIG_ERR;

> return(oact.sa_handler);

>}


>/* Функция-обработчик сигнала */

>static void sig_hndlr(int signo) {

> /* Эта часть кода нам уже не нужна

>  mysignal(SIGINT, sig_hndlr);

> */

> printf("Получен сигнал SIGINT\n");

>}


>main() {

> /* Установим диспозицию */

> mysignal(SIGINT, sig_hndlr);

> mysignal(SIGUSR2, SIG_IGN);

> /* Бесконечный цикл */

> while (1)

>  pause();

>}

Заметим, что при использовании надежных сигналов, не нужно восстанавливать диспозицию в функции-обработчике при получении сигнала.

Группы и сеансы

После создания процесса ему присваивается уникальный идентификатор, возвращаемый системным вызовом fork(2) родительскому процессу. Дополнительно ядро назначает процессу идентификатор группы процессов (process group ID). Группа процессов включает один или более процессов и существует, пока в системе присутствует хотя бы один процесс этой группы. Временной интервал, начинающийся с создания группы и заканчивающийся, когда последний процесс ее покинет, называется временем жизни группы. Последний процесс может либо завершить свое выполнение, либо перейти в другую группу.

Многие системные вызовы могут быть применены как к единичному процессу, так и ко всем процессам группы. Например, системный вызов kill(2) может отправить сигнал как одному процессу, так и всем процессам указанной группы. Точно так же функция waitpid(2) позволяет родительскому процессу ожидать завершения конкретного процесса или любого процесса группы.

Каждый процесс, помимо этого, является членом сеанса (session), являющегося набором одной нескольких групп процессов. Понятие сеанса было введено в UNIX для логического объединения процессов, а точнее, групп процессов, созданных в результате регистрации и последующей работы пользователя в системе. Таким образом, термин "сеанс работы" в системе тесно связан с понятием сеанса, описывающего набор процессов, которые порождены пользователем за время пребывания в системе.