[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 Будильник (alarm clock)

Системный вызов  alarm(2)  используется  для  того,  чтобы  установить
будильник для  процесса, который исполнил этот вызов. Через sec секунд
после вызова  alarm, ядро  генерирует сигнал  SIGALRM и  посылает  его
этому процессу.

Одно  из  использований  alarm(2)  -  установка  предела  времени  для
системных вызовов,  которые могут слишком долго исполняться. Например,
сигнал SIGALRM  может прервать  read(2), который  не получает никакого
ввода с терминала.

В каждый  момент может  существовать только одна установка будильника.
Если следующий  системный вызов  alarm(2) будет  исполнен до того, как
истечет время, установленное предыдущим вызовом, новый вызов возвратит
количество времени,  оставшееся от первой установки (0, если ничего не
было установлено),  и будильник приобретет новое значение. Если задано
0 секунд, будильник будет выключен.
                              БУДИЛЬНИК
alarm(2)

ИМЯ

     alarm - установить будильник для
                   процесса



ИСПОЛЬЗОВАНИЕ

      #include <unistd.h>

      unsigned alarm (unsigned sec);



ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

     время, оставшееся до сигнала
               Ограничение процесса по времени - Пример

Этот полезный пример начинает исполнять какую-либо команду и прерывает
ее, если  она исполняется дольше заданного времени. Команда, у которой
ограничено время  исполнения,  запускается  как  порожденный  процесс.
Будильник устанавливается  на заданное  время,  и  затем  родительский
процесс ожидает,  когда порожденный  завершится. Если до этого момента
возникнет  сигнал   SIGALRM,  то   порожденный  процесс  принудительно
завершается  сигналом   SIGKILL  из   родительской  функции  обработки
сигнала.

14-18     Команда, за  исполнением которой  мы наблюдаем,  запускается
          как порожденный процесс.

19-20     Определяется функция обработки, для того чтобы отреагировать
          на  истечение   времени  будильника.  После  того  будильник
          устанавливается на заданный интервал времени.

21        Здесь процесс  ждет завершения  порожденного процесса.  Если
          wait(2) будет  прерван сигналом, он будет запущен снова, так
          как он  находится внутри  цикла while. Когда истекает время,
          на которое  был установлен будильник, вызывается sigalarm(),
          и wait(2)  возвращает -1.  Следующий вызов  wait(2) в  цикле
          подтверждает "смерть" порожденного процесса.

22-29     Если wait(2)  возвращает неудачу,  проверяется, произошло ли
          это из-за  получения сигнала.  Иначе считается, что возникла
          какая-то ошибка, и цикл прерывается.

35-38     Это  функция  обработки  сигнала  SIGALRM.  Когда  возникает
          сигнал SIGALRM, она убивает порожденный процесс.

Файл: timeout.c
               ОГРАНИЧЕНИЕ ПРОЦЕССА ПО ВРЕМЕНИ - ПРИМЕР

 1    #include <stdio.h>
 2    #include <sys/types.h>
 3    #include <signal.h>
 4    #include <sys/procset.h>
 5    #include <errno.h>
 6    #include <unistd.h>
 7    #define TIMEOUT 10
 8    static int pid;
 9
10    main(int argc, char **argv)
11    {
12          void sigalarm(int);
13          int status;
14          if ((pid = fork()) == 0) {
15              execvp(argv[1], &argv[1]);
16              perror(argv[1]);
17              exit(127);
18          }
19          signal(SIGALRM, sigalarm);
20          alarm(TIMEOUT);
21          while (wait(&status) == -1) {
22              if (errno == EINTR) {
23                 errno = 0;
24                 printf("%s: timed out\n", argv[1]);
25              }
26              else {
27                 perror(argv[0]);
28                 break;
29              }
30          }
31          printf("time remaining: %d\n", alarm(0));
32          exit(WEXITSTATUS(status));
33    }
34
35    void sigalarm(int sig)
36    {
37          sigsend(P_PID, pid, SIGKILL);
38    }