|
Программирование >> Структура ядра и системные вызовы
pause О; * ожидать прерывания сигналом (напримед>д* вводимым посредством клавиатуры) Пробный запуск гфограммы дал следующий результат: % СС sigsetjmp.с % a.out I [1] 377 Return from first time sigsetjmp is called % kill -INT 377 catch signal: 2 Return from signal interruption [1] Done a.out 9.7. API kill Процесс может посылать сигнал в родственный процесс с помощью API kill. Это простое средство предназначено для осуществления межпроцессного взаимодействия и управления процессами. Процесс-отправитель и процесс-получатель должны бьггь связаны таким образом, чтобы реальный или эффективный идентификатор владельца процесса-отправителя совпадал с реальным или эффективным идентификатором владельца процесса-получателя либо чтобы процесс-отправитель имел права привилегированного пользователя. В частности, родительский и порожденный процессы могут посылать сигналы друг другу с помощью интерфейса kill. API kill определен в большинстве систем UNIX и входит в стандарт POSIX.l. Прототип функции этого API выглядит следующим образом: #include <signal.h> int kill ( pld t pid, Int signai num ); Аргумент signaljtum - это номер сигнала, который должен быть послан в один или несколько процессов, обозначенных аргументом pid. Возможные значения pid: Значение pid Влияние на АР! kill Положительное число О Аргумент pid является идентификатором процесса, посылает в него сигнал signal num Посыпает signal mm во все процессы, чей GID совпадает с идентификатором группь! вызывающего процесса Отрицательное число Посылает сигнал signalmm во все процессы, реальный идентификатор владельца которых совпадает с эффективным идентификатором владельца вызывающего процесса. Если эффективный идентификатор владельца вызывающего процесса является идентификатором привилегированного пользователя, то signal mm будет послан во все процессы, созданные в системе (кроме процессов с идентификаторами О и 1). Последний вариант применяется, когда система завершает свою работу - яцро вызывает API kill для прекращения всех процессов за исключением процессов с идентификаторами О и 1. Заметьте, что POSIX.l не определяет поведение API kill, когда значение в/нравно -1. Такая ситуация характерна только для UNIX-систем Посылает signaljium во все процессы, чей GID совпадает с абсолютным значением pid В случае успешного выполнения API М/юзврашает О, а в случае неудачи -1. Ниже на примере программы kill. С показана возможность реализации UNIX-команды kill с помощью API kill: ♦include <iostream.h> ♦include <stdio.h> if-♦include <unistd.h> n. ♦include <string.h> ♦include <signal.h> int main( int argc, ehar** argv} { int pid, sig = SIGTERM; if (argc=-3} if (sscanf(argv[l], %d ,&sig)1=1} { I* получить номер сигнала */ cerr Invalid signal: argv[l] endl; return -1; ) argv++, argc-; ) while {-argOO} if (sscanf(*++argv, %d ,Spid)==1) { /* получить идентификатор процесса */ if (kill (pid, sig)==-l) perror( kill ); . } else cerr Invalid pid: argv[0] endl; return 0; Синтаксис вызова команды kill: kill [-<signal num>] <Pid> ... где <signal num> может быть целым числом или именем сигнала, определенным в заголовке <signal.h>. Аргумент <Pid> - это целое число идентификатора процесса. Может быть указано одно или несколько значений <Pid>, и команда kill будет посылать сигнал <signal num> в процессы с указанным <Pid>. Для упрощения этой программы каждая спецификация сигнала в командной строке должна бьп ь целым значением сигнала. Она не поддерживает символьные имена сигналов. Если номер сигнала не указан, то программа будет использовать стандартный сигнал SIGTERM, как это характерно для UNIX-команды kill Программа вызывает API kill для посылки сигнала в каждый процесс, чей идентификатор указан в командной строке. Если идентификатор процесса недействителен или API Л /выполняется неудачно, то программа устанавливает флаг сообщения об ошибке. 9.8. API alarm API alarm может бьп ь вызван процессом для того, чтобы потребовать от ядра послать через определенное число секунд реального времени сигнал SIGALRM. Это похоже на установку будильника для напоминания о чем-либо через определенный промежуток времени. API alarm определен в большинстве UNIX-систем и входит в стандарт POSIX. 1. Прототип функции этого API выглядит следующим образом: #include <signal.h> unsigned int alarm { unsigned int timejnterval ); Аргумент timejnterval - это время в секундах, по истечении которого ядро пошлет сигнал SIGALRM в вызывающий процесс. Если значение timejnterval равно О, будильник выключается. Возвращаемое значение API alarm - это число секунд, оставшееся до срабатывания таймера процесса и соответствующее установке, которая была сделана в предыдущем системном вызове alarm. Установки, произведенные в результате предыдущего вызова API alarm, отменяются, и таймер процесса сбрасьшается при каждом новом вызове alarm. Таймер процесса не передается в порожденный процесс, созданный функцией fork, но процесс, созданный функцией exec, сохраняет значение таймера, которое было задано до вызова API exec. API alarm может быть использован для реализации API sleep; ; ♦include <stdio.h> ♦include <signal.h> ♦include <unistd.h> void wakeupO {}; . unsigned int sleep ( unsigned int timer ) ( struct sigaction action; ♦ifdef SOLARIS 25 action.sa handler (void (*)(int))wakeup; ♦else action. sa handler * wakeup; ♦endif action.sa flags = 0; sigemptyset(Saction.sa mask) ; if (sigaction (SIGALRM, Section, 0)-=-l) perrorCsigaction ); return 1; } 1Я. (void) alarm ( timer 1 (void)pause 0; return 0; ~ API sleep приостанавливает вызывающий процесс на определенное количество секунд. Процесс пробуждается , когда истекшее время превышает значение timer или когда он прерывается сигналом. В указанном примере функция sleep настраивает обработчик сигнала на сигнал SIGALRM, вызывает API alarm для передачи в ядро запроса на посылку указанного сигнала (по прошествии времени, заданного аргументом timer) и, наконец, приостанавливает его выполнение посредством системного вызова pause. Функция-обработчик сигнала wakeup вызывается тогда, когда сигнал SIGALRM передается в процесс. После возврата из этой функции системный вызов pause прерьшается, происходит возврат в вызывающий процесс из функции sleep. BSD UNIX определяет функцию ualarm, которая похожа на API alarm, но в отличие от последней аргумент и возвращаемое значение функции ualarm выражены в микросекундах. Это полезно для некоторых приложений, где время реакции должно быть порядка микросекунд. Функция ualarm может бьггь использована для реализации BSD-функции usleep, которая похожа на функцию sleep, но ее аргумент задается в микросекундах. 9.9. Интервальные таймеры функция sleep, приостанавливающая процесс на определенное время,- это лишь один из вариантов использования API alarm. Чаще alarm используется для установки в процессе интервального таймера (interval timer). С помощью интервального таймера планируется выполнение процессом определенных задач через фиксированные интервалы времени, осуществляется синхронизация выполнения различных операций, а также ограничивается время, отведенное на выполнение той или иной задачи. На примере программы Птег.С покажем, как установить интервальный таймер реального времени, используя интерфейс alarm: ♦Include <stdio.h> ♦include <unistd.h> ♦Include <signal.h> ♦define INTERVAL 5 void callme( int sig no ) ( alarm( INTERVAL ); /* выполнить запланированные задания */ int main О ( struct sigaction action; sigemptyset(&action.sa mask}; ♦ifdef SOLARIS 25 action.sa handler = (void (*)(int))callme; ♦else action.sa handler= (void (*}(})callme; ♦endif action.sa flags = SA RESTART; if ( sigaction ( SIGALRM,saction,0 )==-l ) perror( sigaction ); return 1; if (alarm( INTERVAsV == -1) perror ( alarm \jsi-else while( 1 ) /* выполнять обычную работу */ return 0; В указанной программе API sigaction вызывается для установки callme как функции обработки сигнала SIGALRM. Потом программа вызывает API alarm для передачи самой себе сигнала SIGALRM через 5 секунд реального времени. Затем программа входит в бесконечный цикл для выполнения обьиных операций. Когда время таймера истекает, вызывается функция callme, которая перезапускает таймер еще на 5 секунд, а потом выполняет запланированные задания. После возврата из функции сайте программа продолжает свою обычную работу до следующего срабатывания таймера. Эта примерная программа может быть полезна при создании программы синхронизации времени: каждый раз, когда вызывается функция callme, она запрашивает текущее время у удаленного хост-компьютера и затем вызывает API stime ддя установления часов локальной системы в соответствии с часами хост-компьютера. В дополнение к интерфейсу alarm для настройки интервального таймера в том или ином процессе в рамках BSD UNIX был создан API seiitimer, который обеспечивает новые (перечислены ниже) возможности. Время в setitimer указывается в микросекундах, тогда как в alarm - в секундах. API alarm может использоваться для установки в процессе только одного таймера реального времени, а API setitimer - для определения до трех различных видов таймеров: а) таймера реального времени; б) таймера времени, затраченного на решение задачи пользователя; в) таймера общего времени, затраченного на решение задачи пользователя и системных задач. API setitimer тлеется также в UNIX System V.3 и V.4, а в стандарте POSIX не определен. POSIX.lb определяет новый набор интерфейсов прикладного программирования, предназначенных для манипулирования интервальными таймерами. Эти API описаны в следующем разделе. В BSD UNIX и UNIX System V определен также API getitimer, который позволяет пользователям запрашивать значения таймера, установленные функцией setitimer. Прототипы функций setitimer и getitimer выглядят таким образом: #include <sys/time.h> int setitimer (int which, const struct itimerval* val, struct itimerval* old); int getitimer (int which, struct Itimerval* old); Аргументы which в этих API указывают, значения таймера какого типа нужно изменять или запрашивать. Возможные значения этого аргумента и соответствующие им типы таймеров перечислены в таблице: Значение аргумента which Тип таймера ITIMER REAL ITIMER VIRTUAL Таймер реального времени. По истечении заданного времени генерирует сигнал SIGALRM Таймер времени, затраченного процессом на задачу пользователя. По истечении заданного времени генерирует сигнал SIGVTALRM
Купить стул компьютерный для школьника Вертикаль. |
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |