Помощь в написании студенческих работ
Антистрессовый сервис

События. 
Операционные системы

РефератПомощь в написанииУзнать стоимостьмоей работы

Если значение pid равно -1, то сигнал посылается всем процессам, у которых реальный код идентификации пользователя совпадает с тем, под которым исполняется процесс, вызвавший функцию killO Если процесс, пославший сигнал, исполняется под кодом идентификации суперпользователя, то сигнал рассылается всем процессам, кроме процессов с идентификаторами 0 и 1; Механизм сигналов представляет собой… Читать ещё >

События. Операционные системы (реферат, курсовая, диплом, контрольная)

Для указания на то, что в системе произошли определенные события, существуют специальные переменные. Для объявления события служит функция post (name of event), для ожидания события — wait (name_of_ event). Для очистки этих переменных используется функция (присваивания нулевого значения) — оператор clear (name of event).

Для функционирования модели событий применяется алгоритм последовательной верхней релаксации (SOR)1 с использованием массива событий, пример применения которого показан на следующем отрезке кода:

float А[ L1U L2 ];

struct event s[ L1 ][ L2 ];

for (i = 0; i < L1; i++)

for (j = 0;j < L2;j++) { clear (s[ij[j ])};

for (j = 0;j < L2-J++) { post (s[ 0][j ])};

for (i = 0;i < L1;i+ +) {post (s[ i ][ 0 ]) };…

parfor (i = 1; i < LI-1; t++) parfor (j = 1;j < L2−1;j++)

<

wait (s[ i-1 ][j]); wait (s[ i ][j-1 ]);

Aim = (A[i-1JUI + A[i+1][j] + AliJU-11 + A[i]U+1])/4; post (sf i ][j ]);

}

Здесь операторы parfor означают циклы, которые можно выполнять параллельно.

Сигналы

Сигналы предназначены для информирования процессов о возникновении асинхронных событий. Для создания сигналов между процессами или ядром и процессами используется функция kill. В настоящее время POSIX определяет 28 сигналов, которые обычно классифицируют следующим образом[1][2]:

  • • сигналы, посылаемые в случае завершения выполнения процесса, т. е. тогда, когда процесс выполняет функцию exit () или функцию signal() с параметром death of child (гибель потомка);
  • • сигналы, посылаемые в случае возникновения особых ситуаций вызываемых процессом, таких как обращение к адресу, находящемуся за пределами виртуального адресного пространства процесса, или попытка записи в область памяти, открытую только для чтения (например, текст программы), или попытка исполнения привилегированной команды, а также различные аппаратные ошибки;
  • • сигналы, посылаемые при возникновении неисправимых ошибок во время выполнения системных функций, таких как исчерпание системных ресурсов во время выполнения функции ехес () после освобождения исходного адресного пространства;
  • • сигналы, причиной которых служит возникновение во время выполнения системной функции совершенно неожиданных ошибок, таких как обращение к несуществующей системной функции (процесс передал номер системной функции, который не соответствует ни одной из имеющихся функций), запись в канал, не связанный ни с одним из процессов чтения, а также использование недопустимого значения в параметре SEEK CUR системной функции lseek (). Казалось бы, более логично в таких случаях вместо посылки сигнала возвращать код ошибки, однако с практической точки зрения для аварийного завершения процессов, в которых возникают подобные ошибки, более предпочтительным является именно использование сигналов;
  • • сигналы, посылаемые процессу, который выполняется в режиме задачи, например, сигнал тревоги (alarm), посылаемый по истечении определенного периода времени, или произвольные сигналы, которыми обмениваются процессы, использующие функцию kill();
  • • сигналы, связанные с терминальным взаимодействием, например, с «зависанием» терминала (когда сигнал-носитель на терминальной линии прекращается по любой причине) или с нажатием клавиш «break» и «delete» на клавиатуре терминала;
  • • сигналы, с помощью которых производится трассировка выполнения процесса.
Концепция сигналов имеет несколько аспектов, основанных на том, каким образом ядро посылает сигнал процессу и каким образом процесс обрабатывает сигнал и управляет реакцией на него. Посылая сигнал процессу, ядро устанавливает в единицу разряд в поле сигнала записи таблицы процессов, соответствующий типу сигнала. Если процесс находится в состоянии приостановки с приоритетом, допускающим прерывания, ядро возобновит его выполнение. На этом роль отправителя сигнала (процесса или ядра) исчерпывается.

Процесс может запоминать сигналы различных типов, но не имеет возможности запоминать количество получаемых сигналов каждого типа. Например, если процесс получает сигнал о «зависании» или об удалении процесса из системы, то он устанавливает в единицу соответствующие разряды в иоле сигналов таблицы процессов, но не может сказать, сколько экземпляров сигнала каждого типа он получил.

Ядро обрабатывает сигналы в контексте того процесса, который получает их, поэтому чтобы обработать сигналы, нужно запустить процесс. Существует три способа обработки сигналов: процесс завершается после получения сигнала, не обращает внимания на сигнал или выполняет особую (пользовательскую) функцию после его получения. Реакцией по умолчанию со стороны процесса, исполняемого в режиме ядра, является вызов функции exit{)> однако с помощью функции signalO процесс может указать другие специальные действия, принимаемые по получении тех или иных сигналов. В UNIX-подобных ОС набор возможных сигналов определен в файле sys/signal.h

Для работы с асинхронными сигналами доступны две функции — одна позволяет программе посылать сигнал самой себе (это называется «поднятием» сигнала):

#include

int raise (int sig);

Посылает сигнал sig, который прерывает нормальное исполнение программы и позволяет обработчику сигнала (если он был определен) взять управление на себя.

Вторая системная функции signalO:

Inti = * signal (int signum, void (*func)(int));

где signum — номер сигнала, при получении которого будет выполнено действие, связанное с запуском пользовательской функции;/мне — адрес функции; Inti — возвращаемое функцией значение. Вместо адреса функции процесс может передавать вызываемой процедуре signal число, равное 1 и 0. Если fune = 1, то процесс будет игнорировать все последующие поступления сигнала с номером signum, если fune = 0 (значение, но умолчанию), то процесс после получения сигнала в режиме ядра завершается.

Для посылки сигналов процессы используют системную функцию killO Синтаксис вызова функции:

#include

#include

int kill (pid_t pid, int signalnum);

где в pid указывается адресат посылаемого сигнала (область действия сигнала), а в signum — номер посылаемого сигнала. Связь между значением pid и совокупностью выполняющихся процессов следующая:

  • • если pid — положительное целое число, то ядро посылает сигнал процессу с идентификатором pid;
  • • если значение pid равно нулю, то сигнал посылается всем процессам, входящим в одну группу с процессом, вызвавшим функцию ?///();
  • • если значение pid равно -1, то сигнал посылается всем процессам, у которых реальный код идентификации пользователя совпадает с тем, под которым исполняется процесс, вызвавший функцию killO Если процесс, пославший сигнал, исполняется под кодом идентификации суперпользователя, то сигнал рассылается всем процессам, кроме процессов с идентификаторами 0 и 1;
  • • если pid — отрицательное целое число, но не -1, то сигнал посылается всем процессам, входящим в группу с номером, равным абсолютному значению pid.

Механизм сигналов представляет собой программное прерывание, посланное процессу, для того, чтобы сообщить о каком-либо событии, ожидаемом или нет. Источник сигнала не может знать отношение к этому получателя, особенно если последний решил игнорировать получение сигнала: источник об этом просто ничего не узнает! Сигналы могут быть посланы:

  • • одним процессом другому: в этом случае используется системный вызов kill ();
  • • от ядра к процессу (например, чтобы указать на фатальную ошибку, вызывающую разрушение процесса).

Параметры обработки, принятые по умолчанию при получении сигнала, можно изменить с помощью специального обработчика (handler). Handler связывается с сигналом посредством вызова signal (). Точно так же сигналы можно игнорировать, используя вызов:

signal (NOMSIGNAL, SIGIGN);

Вызов kill () позволяет послать сигнал процессу (по его PID) или группе процессов (по их PID). Например:

it include

/Обработка, связанная с сигналом прерывания SIGINT */ tint ()

{ /*вывод на экран и выход */ printfi «signal interruption п»); exit (1); }

rnainO

{устанавливается обработчик сигнала SIGINT */.

signal (SI G INT, tint) ;

/*ожидание возможного прерывания */ sleepOOO); exit (0);

;

  • [1] Ноап; С. Л. R. Communicating Sequential Processes // Digital Systems Design. Proceedingsof the Joint IBM University of Newcastle upon Tyne Seminar, 6−9 September 1977 / cd. by B. Shaw. Newcastle University. 1978. P. 145—56.
  • [2] Бах M. Дж. Архитектура операционной системы UNIX.
Показать весь текст
Заполнить форму текущей работой