Читаем UNIX — универсальная среда программирования полностью

 signal(SIGQUIT, qstat);

 return status;

}

Несколько слов по поводу описаний: функция signal, очевидно, имеет довольно странный второй аргумент. Фактически он представляет собой указатель на функцию, поставляющую целое значение, и в то же время это тип самой подпрограммы сигнала. Две величины, SIG_IGN и SIG_DFL, имеют правильный тип, но выбраны так, что не совпадают ни с одной из существующих функции. Для любознательных покажем, как они определены для PDP-11 и VAX: определения, видимо, достаточно "неуклюжи", чтобы стимулировать использование signal.h.

#define SIG_DFL (int(*))0

#define SIG_IGM (int(*))1

Будильники

Системный вызов alarm(n) обеспечивает посылку сигнала SIGALRM вашему процессу через n секунд. Сигнал будильника может быть использован для того, чтобы удостовериться в возникновении каких-то событий за соответствующее время. Если что-нибудь произошло, сигнал будильника может быть выключен; в противном случае процесс может получить управление, перехватив этот сигнал.

Для иллюстрации приведем программу timeout, которая запускает другую команду; если команда не закончила свое выполнение за определенное время, она будет завершена по звонку будильника. Например, вспомните команду watchfor из гл. 5. Вместо того чтобы запускать ее без ограничения времени работы, установите ограничение в часах:

$ timeout -3600 watchfor dmg

Программа timeout демонстрирует почти все возможности, которые мы обсуждали в последних двух разделах. Создан процесс-потомок, родительский процесс устанавливает будильник и затем ждет, пока потомок завершит работу. Если будильник "зазвенел" первым, потомок уничтожается. Делается попытка вернуть состояние потомка при выходе.

/* timeout: set time limit on a process */

#include stdio.h

#include signal.h

int pid; /* child process id */

char *progname;

main(argc, argv)

 int argc;

 char *argv[];

{

 int sec = 10, status, onalarm;

 progname = argv[0];

 if (argc 1 argv[1][0] == '-') {

  sec = atoi(argv[1][1]);

  argc--;

  argv++;

 }

 if (argc 2)

  error("Usage: %s [-10] command", progname);

 if ((pid=fork) == 0) {

  execvp(argv[1], argv[1]);

  error("couldn't start %s", argv[1]);

 }

 signal(SIGALRM, onalarm);

 alarm(sec);

 if (wait(status) == -1 || (status 0177) != 0)

  error("%s killed", argv[1]);

 exit((status 8) 0377);

}

onalarm /* kill child when alarm arrives */

{

 kill(pid, SIGKILL);

}

Упражнение 7.18

Можете ли вы представить, как реализована sleep? Подсказка: pause(2). При каких обстоятельствах (если это вообще возможно) sleep и alarm могли бы помешать друг другу?

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