Морис Бах - Архитектура операционной системы UNIX
- Название:Архитектура операционной системы UNIX
- Автор:
- Жанр:
- Издательство:Издано корпорацией Prentice-Hall.
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Морис Бах - Архитектура операционной системы UNIX краткое содержание
Архитектура операционной системы UNIX - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Ядро проверяет получение сигнала, когда процесс собирается перейти из режима ядра в режим задачи, а также когда он переходит в состояние приостанова или выходит из этого состояния с достаточно низким приоритетом планирования (см.Рисунок 7.6). Ядро обрабатывает сигналы только тогда, когда процесс возвращается из режима ядра в режим задачи. Таким образом, сигнал не оказывает немедленного воздействия на поведение процесса, исполняемого в режиме ядра. Если процесс исполняется в режиме задачи, а ядро тем временем обрабатывает прерывание, послужившее поводом для посылки процессу сигнала, ядро распознает и обработает сигнал по выходе из прерывания. Таким образом, процесс не будет исполняться в режиме задачи, пока какие-то сигналы остаются необработанными.
На Рисунке 7.7 представлен алгоритм, с помощью которого ядро определяет, получил ли процесс сигнал или нет. Условия, в которых формируются сигналы типа «гибель потомка», будут рассмотрены позже. Мы также увидим, что процесс может игнорировать отдельные сигналы, если воспользуется функцией signal. В алгоритме issig ядро просто гасит индикацию тех сигналов, на которые процесс не желает обращать внимание, и привлекает внимание процесса ко всем остальным сигналам.

Рисунок 7.6. Диаграмма переходов процесса из состояние в состояние с указанием моментов проверки и обработки сигналов
алгоритм issig /* проверка получения сигналов */
входная информация: отсутствует
выходная информация:
«истина», если процесс получил сигналы, которые его интересуют
«ложь» — в противном случае
{
do while (поле в записи таблицы процессов, содержащее индикацию о получении сигнала, хранит ненулевое значение)
{
найти номер сигнала, посланного процессу;
if (сигнал типа «гибель потомка»)
{
if (сигналы данного типа игнорируются)
освободить записи таблицы процессов, которые соответствуют потомкам, прекратившим существование;
else
if (сигналы данного типа принимаются)
return (true);
}
else
if (сигнал не игнорируется) return (true);
сбросить (погасить) сигнальный разряд, установленный в соответствующем поле таблицы процессов, хранящем индикацию получения сигнала;
}
return (false);
}
Рисунок 7.7. Алгоритм опознания сигналов
7.2.1 Обработка сигналов
Ядро обрабатывает сигналы в контексте того процесса, который получает их, поэтому чтобы обработать сигналы, нужно запустить процесс. Существует три способа обработки сигналов: процесс завершается по получении сигнала, не обращает внимание на сигнал или выполняет особую (пользовательскую) функцию по его получении. Реакцией по умолчанию со стороны процесса, исполняемого в режиме ядра, является вызов функции exit, однако с помощью функции signal процесс может указать другие специальные действия, принимаемые по получении тех или иных сигналов.
Синтаксис вызова системной функции signal:
oldfunction = signal(signum, function);
где signum — номер сигнала, при получении которого будет выполнено действие, связанное с запуском пользовательской функции, function — адрес функции, oldfunction — возвращаемое функцией значение. Вместо адреса функции процесс может передавать вызываемой процедуре signal числа 1 и 0: если function = 1, процесс будет игнорировать все последующие поступления сигнала с номером signum (особый случай, связанный с игнорированием сигнала «гибель потомка», рассматривается в разделе 7.4), если = 0 (значение по умолчанию), процесс по получении сигнала в режиме ядра завершается. В пространстве процесса поддерживается массив полей для обработки сигналов, по одному полю на каждый определенный в системе сигнал. В поле, соответствующем сигналу с указанным номером, ядро сохраняет адрес пользовательской функции, вызываемой по получении сигнала процессом. Способ обработки сигналов одного типа не влияет на обработку сигналов других типов.
алгоритм psig /* обработка сигналов после проверки их существования */
входная информация: отсутствует
выходная информация: отсутствует
{
выбрать номер сигнала из записи таблицы процессов;
очистить поле с номером сигнала;
if (пользователь ранее вызывал функцию signal, с помощью которой сделал указание игнорировать сигнал данного типа)
return;
if (пользователь указал функцию, которую нужно выполнить по получении сигнала)
{
из пространства процесса выбрать пользовательский виртуальный адрес функции обработки сигнала;
/* следующий оператор имеет нежелательные побочные эффекты */
очистить поле в пространстве процесса, содержащее адрес функции обработки сигнала;
внести изменения в пользовательский контекст:
искусственно создать в стеке задачи запись, имитирующую обращение к функции обработки сигнала;
внести изменения в системный контекст:
записать адрес функции обработки сигнала в поле счетчика команд, принадлежащее сохраненному регистровому контексту задачи;
return;
}
if (сигнал требует дампирования образа процесса в памяти)
{
создать в текущем каталоге файл с именем «core»;
переписать в файл «core» содержимое пользовательского контекста;
}
немедленно запустить алгоритм exit;
}
Рисунок 7.8. Алгоритм обработки сигналов
Обрабатывая сигнал (Рисунок 7.8), ядро определяет тип сигнала и очищает (гасит) разряд в записи таблицы процессов, соответствующий данному типу сигнала и установленный в момент получения сигнала процессом. Если функции обработки сигнала присвоено значение по умолчанию, ядро в отдельных случаях перед завершением процесса сбрасывает на внешний носитель (дампирует) образ процесса в памяти (см. упражнение 7.7). Дампирование удобно для программистов тем, что позволяет установить причину завершения процесса и посредством этого вести отладку программ. Ядро дампирует состояние памяти при поступлении сигналов, которые сообщают о каких-нибудь ошибках в выполнении процессов, как например, попытка исполнения запрещенной команды или обращение к адресу, находящемуся за пределами виртуального адресного пространства процесса. Ядро не дампирует состояние памяти, если сигнал не связан с программной ошибкой. Например, прерывание, вызванное нажатием клавиш «delete» или «break» на терминале, имеет своим результатом посылку сигнала, который сообщает о том, что пользователь хочет раньше времени завершить процесс, в то время как сигнал о «зависании» является свидетельством нарушения связи с регистрационным терминалом. Эти сигналы не связаны с ошибками в протекании процесса. Сигнал о выходе (quit), однако, вызывает сброс состояния памяти, несмотря на то, что он возникает за пределами выполняемого процесса. Этот сигнал, обычно вызываемый одновременным нажатием клавиш ‹Ctrl/|›, дает программисту возможность получать дамп состояния памяти в любой момент после запуска процесса, что бывает необходимо, если процесс попадает в бесконечный цикл выполнения одних и тех же команд (зацикливается).
Читать дальшеИнтервал:
Закладка: