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);
}
Можете ли вы представить, как реализована sleep
? pause(2)
. При каких обстоятельствах (если это вообще возможно) sleep
и alarm
могли бы помешать друг другу?