- •Сигналы:
- •Группы и сеансы
- •Управление сигналами
- •Отправление сигнала
- •Взаимодействие между процессами
- •Int pipe(int *fieldes);
- •Int mknod(char *pathname, int mode, int dev);
- •Сообщения
- •Int msgget(key_t key, int msgflag);
- •Int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
- •Int msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
- •Int semget(key_t key, int nsems, int semflag);
- •Int semop(int semid,
- •0, 1, 0}; /* Затем увеличить значение
- •0,1,0 /*Увеличить значение семафора на 1*/
- •Int shmget(key_t key, int size, int shmflag);
- •Int *shmat( int shmid, char *shmaddr, int shmflag);
- •Int shmdt(char *shmaddr);
- •Int segment;
- •Int shmid, semid;
Сигналы:
обслуживание сигналов операционной системой.
Простейшая форма межпроцессного взаимодействия, позволяющая уведомлять процесс или группу процессов о наступлении некоторого события.
сигналы с точки зрения пользователя и программиста – в л.р.
Группы и сеансы
Такое представление набора процессов используется в UNIX для управления доступом к терминалу и поддержки пользовательских сеансов работы в системе.
Основные понятия:
- Группа процессов. Каждый процесс принадлежит определенной группе процессов. Каждая группа имеет уникальный идентификатор. Группа может иметь в своем составе лидера группы — процесс, чей идентификатор PID равен идентификатору группы. Обычно процесс наследует группу от родителя, но может покинуть ее и организовать собственную группу.
- Управляющий терминал. Процесс может быть связан с терминалом, который называется управляющим. Все процессы группы имеют один и тот же управляющий терминал.
- Специальный файл устройства /dev/tty. Этот файл связан с управляющим терминалом процесса. Драйвер для этого псевдоустройства по существу перенаправляет запросы на фактический терминальный драйвер, который может быть различным для различных процессов. Например, два процесса, принадлежащие различным сеансам, открывая файл /dev/tty, получат доступ к различным терминалам.
Управление сигналами
Сигналы обеспечивают механизм вызова определенной процедуры при наступлении некоторого события.
Каждое событие имеет свой идентификатор и символьную константу.
Некоторые из этих событий имеют асинхронный характер, например, когда пользователь нажимает клавишу <Del> или <Сtгl>+<С> для завершения выполнения процесса, другие являются уведомлением об ошибках и особых ситуациях, например, при попытке доступа к недопустимому адресу или вызовы недопустимой инструкции.
фазы механизма сигналов
генерация (или отправление сигнала)
его доставка и обработка.
Сигнал отправляется, когда происходит определенное событие, о наступлении которого должен быть уведомлен процесс.
Сигнал считается доставленным, когда процесс, которому был отправлен сигнал, получает его и выполняет его обработку.
В промежутке между этими двумя моментами сигнал ожидает доставки.
Отправление сигнала
Ядро генерирует и отправляет процессу сигнал в ответ на ряд событий, которые могут быть вызваны самим процессом, другим процессом, прерыванием или какими-либо внешними событиями.
основные причины отправки сигнала:
-
Особые ситуации
Когда выполнение процесса вызывает особую ситуацию, например, деление на ноль, процесс получает соответствующий сигнал.
Терминальные прерывания
Нажатие некоторых клавиш терминала, например, <Dе1>, <Ctrl>+<С> или <Ctrl>+<\>, вызывает отправление сигнала текущему процессу, связанному с терминалом.
Другие процессы
Процесс может отправить сигнал другому процессу или группе процессов с помощью системного вызова kill(). В этом случае сигналы являются элементарной формой межпроцессного взаимодействия.
Управление заданиями
Командные интерпретаторы, поддерживающие систему управления заданиями, используют сигналы для манипулирования фоновым и текущими задачами. Когда процесс, выполняющийся в фоновом режиме делает попытку чтения или записи на терминал, ему отправляется сигнал останова. Когда дочерний процесс завершает свою работу, родитель уведомляется об этом также с помощью сигнала.
Квоты
Когда процесс превышает выделенную ему квоту вычислительных ресурсов или ресурсов файловой системы, ему отправляется соответствующий сигнал.
Уведомления
Процесс может запросить уведомление о наступлении тех или иных событий, например, готовности устройства и т. д. Такое уведомление отправляется процессу в виде сигнала.
Алармы
Если процесс установил таймер, ему будет отправлен сигнал, когда значение таймера станет равным нулю.
Доставка и обработка сигнала
Для каждого сигнала в системе определена обработка по умолчанию, которую выполняет ядро, если процесс не указал другого действия.
В общем случае - возможные действия:
-завершить выполнение процесса,
-игнорировать сигнал,
-остановить процесс
-продолжить процесс (справедливо для остановленного процесса, для остальных сигнал игнорируется),
наиболее употребительным из которых является первое.
Процесс может
изменить действие по умолчанию,
либо зарегистрировать собственный обработчик сигнала,
либо указать, что сигнал следует игнорировать.
заблокировать сигнал, отложив на некоторое время его обработку.
Это возможно не для всех сигналов. Например, для сигналов SIGKILL (сигнал, при получении которого вып-ние процесса прекращается) и SIGSTOP (остаглвка выплнения процесса от Ctrl-z) единственным действием является действие по умолчанию, эти сигналы нельзя ни перехватить, ни заблокировать, ни игнорировать
любая обработка сигнала, в том числе обработка по умолчанию, подразумевает, что процесс выполняется.
На системах с высокой загрузкой это может привести к существенным задержкам между отправлением и доставкой сигнала, т. к. процесс не получит сигнал, пока не будет выбран планировщиком, и ему не будут предоставлены вычислительные ресурсы.
Этот вопрос был затронут при разговоре о точности таймеров, которые может использовать процесс.
Доставка сигнала происходит после того, как ядро от имени процесса вызывает системную процедуру issig(), которая проверяет, существуют ли ожидающие доставки сигналы, адресованные данному процессу.
Функция issig() вызывается ядром в трех случаях:
- Непосредственно перед возвращением из режима ядра в режим задачи после обработки системного вызова или прерывания.
- Непосредственно перед переходом процесса в состояние сна с приоритетом, допускающим прерывание сигналом.
- Сразу же после пробуждения после сна с приоритетом, допускающим прерывание сигналом.
Если процедура issig() обнаруживает ожидающие доставки сигналы, ядро вызывает функцию доставки сигнала, которая выполняет действия по умолчанию или вызывает специальную функцию sendsig(), запускающую обработчик сигнала, зарегистрированный процессом.
Функция sendsig() возвращает процесс в режим задачи, передает управление обработчику сигнала, а затем восстанавливает контекст процесса для продолжения прерванного сигналом выполнения.
Рассмотрим типичные ситуации, связанные с отправлением и доставкой сигналов. Допустим, пользователь, работая за терминалом, нажимает клавишу прерывания (<Del> или <Сtгl>+<С> для большинства систем). Нажатие любой клавиши вызывает аппаратное прерывание (например, прерывание от последовательного порта), а драйвер терминала при обработке этого прерывания определяет, что была нажата специальная клавиша, генерирующая сигнал, и отправляет текущему процессу, связанному с терминалом, сигнал SIGINT. Когда процесс будет выбран планировщиком и запущен на выполнение, при переходе в режим задачи он обнаружит поступление сигнала и обработает его. Если же в момент генерации сигнала терминальным драйвером процесс, которому был адресован сигнал, уже выполнялся (т. е. был прерван обработчиком терминального прерывания), он также обработает сигнал при возврате в режим задачи после обработки прерывания.
Работа с сигналами, связанными с особыми ситуациями, незначительно отличается от вышеописанной. Особая ситуация возникает при выполнении процессом определенной инструкции, вызывающей в системе ошибку (например, деление на ноль, обращение к недопустимой области памяти, недопустимая инструкция или вызов и т. д.). Если такое происходит, вызывается системный обработчик особой ситуации, и процесс переходит в режим ядра, почти так же, как и при обработке любого другого прерывания. Обработчик отправляет процессу соответствующий сигнал, который доставляется, когда выполнение возвращается в режим задачи.
При обсуждении состояния сна процесса мы выделили две категории событий, вызывающих состояние сна процесса: допускающие прерывание сигналом и не допускающие такого прерывания. В последнем случае сигнал будет терпеливо ожидать нормального пробуждения процесса, например, после завершения операции дискового ввода/вывода.
В первом случае, доставка сигнала будет проверена ядром непосредственно перед переходом процесса в состояние сна. Если такой сигнал поступил, будет вызван обработчик сигнала, а системный вызов, который выполнялся процессом, будет аварийно завершен с ошибкой EINTR. Если генерация сигнала произошла в течение сна процесса, ядро .будет вынуждено разбудить его и снять прерванный системный вызов (ошибка EINTR). После пробуждения процесса либо вследствие получения сигнала, либо из-за наступления ожидаемого события, ядром будет вызвана функция issig(), которая обнаружит поступление сигнала и вызовет соответствующую обработку (В BSD UNIX были введено понятие перезапускаемых системных вызовов. Суть этого механизма заключается в том, что прерванный сигналом системный вызов автоматически повторяется после обработки сигнала, вместо аварийного завершения с ошибкой етмтк. Допускается отключение этой возможности для конкретных сигналов.).