Читаем Операционная система UNIX полностью

Если процедура issig() обнаруживает ожидающие доставки сигналы, ядро вызывает функцию доставки сигнала, которая выполняет действия по умолчанию или вызывает специальную функцию sendsig(), запускающую обработчик сигнала, зарегистрированный процессом. Функция sendsig() возвращает процесс в режим задачи, передает управление обработчику сигнала, а затем восстанавливает контекст процесса для продолжения прерванного сигналом выполнения.

Рассмотрим типичные ситуации, связанные с отправлением и доставкой сигналов. Допустим, пользователь, работая за терминалом, нажимает клавишу прерывания (<Del> или <Ctrl>+<C> для большинства систем). Нажатие любой клавиши вызывает аппаратное прерывание (например, прерывание от последовательного порта), а драйвер терминала при обработке этого прерывания определяет, что была нажата специальная клавиша, генерирующая сигнал, и отправляет текущему процессу, связанному с терминалом, сигнал SIGINT. Когда процесс будет выбран планировщиком и запущен на выполнение, при переходе в режим задачи он обнаружит поступление сигнала и обработает его. Если же в момент генерации сигнала терминальным драйвером процесс, которому был адресован сигнал, уже выполнялся (т.е. был прерван обработчиком терминального прерывания), он также обработает сигнал при возврате в режим задачи после обработки прерывания.

Работа с сигналами, связанными с особыми ситуациями, незначительно отличается от вышеописанной. Особая ситуация возникает при выполнении процессом определенной инструкции, вызывающей в системе ошибку (например, деление на ноль, обращение к недопустимой области памяти, недопустимая инструкция или вызов и т.д.). Если такое происходит, вызывается системный обработчик особой ситуации, и процесс переходит в режим ядра, почти так же, как и при обработке любого другого прерывания. Обработчик отправляет процессу соответствующий сигнал, который доставляется, когда выполнение возвращается в режим задачи.

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

В первом случае, доставка сигнала будет проверена ядром непосредственно перед переходом процесса в состояние сна. Если такой сигнал поступил, будет вызван обработчик сигнала, а системный вызов, который выполнялся процессом, будет аварийно завершен с ошибкой EINTR. Если генерация сигнала произошла в течение сна процесса, ядро будет вынуждено разбудить его и снять прерванный системный вызов (ошибка EINTR). После пробуждения процесса либо вследствие получения сигнала, либо из-за наступления ожидаемого события, ядром будет вызвана функция issig(), которая обнаружит поступление сигнала и вызовет соответствующую обработку.[41]

<p>Взаимодействие между процессами</p>

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

Для реализации взаимодействия требуется:

□ обеспечить средства взаимодействия между процессами и одновременно

□ исключить нежелательное влияние одного процесса на другой.

Взаимодействие между процессами необходимо для решения следующих задач:

□ Передача данных. Один процесс передает данные другому процессу, при этом их объем может варьироваться от десятков байтов до нескольких мегабайтов.

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

□ Извещения. Процесс может известить другой процесс или группу процессов о наступлении некоторого события. Это может понадобиться, например, для синхронизации выполнения нескольких процессов.

Очевидно, что решать данную задачу средствами самих процессов неэффективно, а в рамках многозадачной системы — опасно и потому невозможно. Таким образом, сама операционная система должна обеспечить механизмы межпроцессного взаимодействия (Inter-Process Communication, IPC).

К средствам межпроцессного взаимодействия, присутствующим во всех версиях UNIX, можно отнести:

□ сигналы

□ каналы

□ FIFO (именованные каналы)

□ сообщения (очереди сообщений)

□ семафоры

□ разделяемую память

Перейти на страницу:

Похожие книги