Читаем UNIX полностью

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

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

$ timeout -3600 watchfor dmg &

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

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

#include

#include

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 могли бы помешать друг другу?

Перейти на страницу:

Похожие книги