Андрей Робачевский - Операционная система UNIX
- Название:Операционная система UNIX
- Автор:
- Жанр:
- Издательство:BHV - Санкт-Петербург
- Год:1997
- Город:Санкт-Петербург
- ISBN:5-7791-0057-8
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Андрей Робачевский - Операционная система UNIX краткое содержание
Книга посвящена семейству операционных систем UNIX и содержит информацию о принципах организации, идеологии и архитектуре, объединяющих различные версии этой операционной системы.
В книге рассматриваются: архитектура ядра UNIX (подсистемы ввода/вывода, управления памятью и процессами, а также файловая подсистема), программный интерфейс UNIX (системные вызовы и основные библиотечные функции), пользовательская среда (командный интерпретатор shell, основные команды и утилиты) и сетевая поддержка в UNIX (протоколов семейства TCP/IP, архитектура сетевой подсистемы, программные интерфейсы сокетов и TLI).
Для широкого круга пользователей
Операционная система UNIX - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
#include
void(*signal(int sig, void (*disp)(int)))(int);
Аргумент sig
определяет сигнал, диспозицию которого нужно изменить.
Аргумент disp
определяет новую диспозицию сигнала, которой может быть определенная пользователем функция-обработчик или одно из следующих значений:
SIG_DFL |
Указывает ядру, что при получении процессом сигнала необходимо вызвать системный обработчик, т.е. выполнить действие по умолчанию. |
SIG_IGN |
Указывает, что сигнал следует игнорировать. Напомним, что не все сигналы можно игнорировать. |
В случае успешного завершения signal(3C) возвращает предыдущую диспозицию — это может быть функция-обработчик сигнала или системные значения SIG
_DFL или SIG_IGN
. Возвращаемое значение может быть использовано для восстановления диспозиции в случае необходимости.
Использование функции signal(3C) подразумевает семантику устаревших или ненадежных сигналов. Процесс при этом имеет весьма слабые возможности управления сигналами. Во-первых, процесс не может заблокировать сигнал, т. е. отложить получение сигнала на период выполнения критического участка кода. Во-вторых, каждый раз при получении сигнала, его диспозиция устанавливается на действие по умолчанию. Данная функция и соответствующая ей семантика сохранены для поддержки старых версий приложений. В связи с этим в новых приложениях следует избегать использования функции signal(3C) . Тем не менее для простейшей иллюстрации использования сигналов, приведенный ниже пример использует именно этот интерфейс:
#include
/* Функция-обработчик сигнала */
static void sig_hndlr(int signo) {
/* Восстановим диспозицию */
signal(SIGINT, sig_hndlr);
printf("Получен сигнал SIGINT\n");
}
main() {
/* Установим диспозицию */
signal(SIGINT, sih_hndlr);
signal(SIGUSR1, SIG_DFL);
signal(SIGUSR2, SIG_IGN);
/* Бесконечный цикл */
while(1)
pause();
}
В этом примере изменена диспозиция трех сигналов: SIGINT
, SIGUSR1
и SIGUSR2
. При получении сигнала SIGINT
вызывается обработчик при получении сигнала SIGUSR1
производится действие по умолчанию (процесс завершает работу), а сигнал SIGUSR2
игнорируется. После установки диспозиции сигналов процесс запускает бесконечный цикл, в процессе которого вызывается функция pause(2) . При получении сигнала, который не игнорируется, pause(2) возвращает значение -1, а переменная errno устанавливается равной EINTR
. Заметим, что каждый раз при получении сигнала SIGINT
мы вынуждены восстанавливать требуемую диспозицию, в противном случае получение следующего сигнала этого типа вызвало бы завершение выполнения процесса (действие по умолчанию).
При запуске программы, получим следующий результат:
$ а.out &
[1] 8365
PID порожденного процесса
$ kill -SIGINT 8365
Получен сигнал SIGINT
Сигнал SIGINT перехвачен
$ kill -SIGUSR2 8365
Сигнал SIGUSR2 игнорируется
$ kill -SIGUSR1 8365
[1]+ User Signal 1
Сигнал SIGUSR1 вызывает завер-
a.out
шение выполнения процесса
$
Для отправления сигналов процессу использована команда kill(1) , описанная в предыдущей главе.
Надежные сигналы
Стандарт POSIX. 1 определил новый набор функций управления сигналами. основанный на интерфейсе 4.2BSD UNIX и лишенный рассмотренных выше недостатков.
Модель сигналов, предложенная POSIX, основана на понятии набора сигналов (signal set), описываемого переменной типа sigset_t
. Каждый бит этой переменной отвечает за один сигнал. Во многих системах тип sigset_t
имеет длину 32 бита, ограничивая количество возможных сигналов числом 32.
Следующие функции позволяют управлять наборами сигналов:
#include
int sigempyset(sigset_t *set);
int siufillset(sigset_t *set);
int sigaddset(sigset_t *set, int signo);
int sigdelset(sigset_t *set, int signo);
int sigismember(sigset_t *set, int signo);
В отличие от функции signal(3C) , изменяющей диспозицию сигналов, данные функции позволяют модифицировать структуру данных sigset_t
, определенную процессом. Для управления непосредственно сигналами используются дополнительные функции, которые мы рассмотрим позже.
Функция sigemptyset(3C) инициализирует набор, очищая все биты. Если процесс вызывает sigfillset(3C) , то набор будет включать все сигналы, известные системе. Функции sigaddset(3C) и sigdelset(3C) позволяют добавлять или удалять сигналы набора. Функция sigismember(3C) позволяет проверить, входит ли указанный параметром signo
сигнал в набор.
Вместо функции signal(3C) стандарт POSIX. 1 определяет функцию sigaction(2) , позволяющую установить диспозицию сигналов, узнать ее текущее значение или сделать и то и другое одновременно. Функция имеет следующее определение:
#include
int sigaction (int sig, const struct sigaction *act,
struct sigaction *oact);
Вся необходимая для управлением сигналами информация передается через указатель на структуру sigaction
, имеющую следующие поля:
void (*sa_handler)() |
Обработчик сигнала sig |
void (*sa_sigaction)(int, siginfo_t*, void*) |
Обработчик сигнала sig при установленном флаге SA_SIGINFO |
sigset_t sa_mask |
Маска сигналов |
int sa_flags |
Флаги |
Поле sa_handler
определяет действие, которое необходимо предпринять при получении сигналов, и может принимать значения SIG_IGN
, SIG_DFL
или адреса функции-обработчика. Если значение sa_handler
или sa_sigaction
не равны NULL
, то в поле sa_mask
передается набор сигналов, которые будут добавлены к маске сигналов перед вызовом обработчика. Каждый процесс имеет установленную маску сигналов, определяющую сигналы, доставка которых должна быть заблокирована. Если определенный бит маски установлен, соответствующий ему сигнал будет заблокирован. После возврата из функции-обработчика значение маски возвращается к исходному значению. Заметим, что сигнал, для которого установлена функция-обработчик, также будет заблокирован перед ее вызовом. Такой подход гарантирует, что во время обработки, последующее поступление определенных сигналов будет приостановлено до завершения функции. Как правило, UNIX не поддерживает очередей сигналов, и это значит, что блокировка нескольких однотипных сигналов в конечном итоге вызовет доставку лишь одного.
Поле sa_flags
определяет флаги, модифицирующие доставку сигнала. Оно может принимать следующие значения:
SA_ONSTACK |
Если определена функция-обработчик сигнала, и с помощью функции sigaltstack(2) задан альтернативный стек для функции-обработчика, то при обработке сигнала будет использоваться этот стек. Если флаг не установлен, будет использоваться обычный стек процесса. |
SA_RESETHAND * |
Если определена функция-обработчик, то диспозиция сигнала будет изменена на SIG_DFL , и сигнал не будет блокироваться при запуске обработчика. Если флаг не установлен, диспозиция сигнала остается неизменной. |
SA_NODEFER * |
Если определена функция-обработчик, то сигнал блокируется на время обработки только в том случае, если он явно указан в поле sa_mask . Если флаг не установлен, в процессе обработки данный сигнал автоматически блокируется. |
SA_RESTART |
Если определена функция-обработчик, ряд системных вызовов, выполнение которых было прервано полученным сигналом, будут автоматически перезапущены после обработки сигнала. [25] К таким системным вызовам, в частности, относятся read(2) и write(2) для медленных устройств, таких как терминалы, а также ioctl(2) , fcntl(2) , wait(2) и waitpid(2) .Если флаг не установлен, системный вызов возвратит ошибку EINTR . |
SA_SIGINFO * |
Если диспозиция указывает на перехват сигнала, вызывается функция, адресованная полем sa_sigaction . Если флаг не установлен, вызывается обработчик sa_handler . |
SA_NOCLDWAIT * |
Если указанный аргументом sig сигнал равен SIGCHLD , при завершении потомки не будут переходить в состояние зомби. Если процесс в дальнейшем вызовет функции wait(2) , wait3(2) , waitid(2) или waitpid(2) , их выполнение будет блокировано до завершения работы всех потомков данного процесса. |
SA_NOCLDSTOP * |
Если указанный аргументом sig сигнал равен SIGCHLD , указанный сигнал не будет отправляться процессу при завершении или останове любого из его потомков. |
*Данные флаги не определены для UNIX BSD.
Читать дальшеИнтервал:
Закладка: