Чтение онлайн

на главную - закладки

Жанры

Linux программирование в примерах
Шрифт:

Из этих трех таймеров

ITIMER_REAL
кажется наиболее полезным. Следующая программа,
ch14-timers.c
, показывает, как читать данные с терминала, но с тайм-аутом, чтобы программа не зависала на бесконечное время, ожидая ввода:

1 /* ch14-timers.c --- демонстрация интервальных таймеров */

2

3 #include <stdio.h>

4 #include <assert.h>

5 #include <signal.h>

6 #include <sys/time.h>

7

8 /* handler ---
обрабатывает SIGALRM */

9

10 void handler(int signo)

11 {

12 static const char msg[] = "\n*** Timer expired, you lose ***\n";

13

14 assert(signo == SIGALRM);

15

16 write(2, msg, sizeof(msg) - 1);

17 exit(1);

18 }

19

20 /* main --- установить таймер, прочесть данные с тайм-аутом */

21

22 int main(void)

23 {

24 struct itimerval tval;

25 char string[BUFSIZ];

26

27 timerclear(&tval.it_interval); /* нулевой интервал означает не сбрасывать таймер */

28 timerclear(&tval.it_value);

29

30 tval.it_value.tv_sec = 10; /* тайм-аут 10 секунд */

31

32 (void)signal(SIGALRM, handler);

33

34

35 printf("You have ten seconds to enter\nyour name, rank, and serial number: ");

36 (void)setitimer(ITIMER_REAL, &tval, NULL);

37 if (fgets(string, sizeof string, stdin) != NULL) {

38 (void)setitimer(ITIMER_REAL, NULL, NULL); /* выключить таймер */

39 /* обработать оставшиеся данные, вывод диагностики для иллюстрации */

40 printf("I'm glad you are being cooperative.\n");

41 } else

42 printf("\nEOF, eh? We won't give up so easily'\n");

43

44 exit(0);

45 }

Строки 10–18 представляют обработчик сигнала для

SIGALRM
; вызов
assert
гарантирует, что обработчик сигнала был установлен соответствующим образом. Тело обработчика выводит сообщение и выходит, но оно может делать что-нибудь более подходящее для крупномасштабной программы.

В функции

main
строки 27–28 очищают два члена
struct timeval
структуры
struct itimerval.tval
. Затем строка 30 устанавливает тайм-аут в 10 секунд. Установка
tval.it_interval
в 0 означает, что нет повторяющегося сигнала; он срабатывает лишь однажды. Строка 32 устанавливает обработчик сигнала, а строка 34 выводит приглашение.

Строка 36 устанавливает таймер, а строки 37–42 выводят соответствующие сообщения, основываясь на действиях пользователя. Реальная программа выполняла бы в этот момент свою задачу. Важно здесь обратить внимание на строку 38, которая отменяет таймер, поскольку были введены действительные данные.

ЗАМЕЧАНИЕ. Между строками 37 и 38 имеется намеренное состояние гонки. Все дело в том, что если пользователь не вводит строку в течение отведенного таймером времени, будет доставлен сигнал, и обработчик сигнала выведет сообщение «you lose».

Вот три успешных запуска программы:

$ ch14-timers /* Первый запуск, ничего не вводится */

You have ten seconds to enter

your name, rank, and serial number:

*** Timer expired, you lose ***

$ ch14-timers /* Второй запуск, ввод данных */

You have ten seconds to enter

your name, rank, and serial number: Jamas Kirk, Starfleet Captain, 1234

I'm glad you are being cooperative.

$ ch14-timers /* Третий запуск, ввод EOF (^D) */

You have ten seconds to enter

your name, rank, and serial number: ^D

EOF, eh? We won't give up so easily!

POSIX оставляет неопределенным, как интервальные таймеры взаимодействуют с функцией

sleep
, если вообще взаимодействуют. GLIBC не использует для реализации
sleep
функцию
alarm
, поэтому на системах GNU/Linux
sleep
не взаимодействует с интервальным таймером. Однако, для переносимых программ, вы не можете делать такое предположение.

14.3.4. Более точные паузы:

nanosleep

Функция

sleep
(см. раздел 10.8.1 «Сигнальные часы:
sleep
,
alarm
и
SIGALRM
») дает программе возможность приостановиться на указанное число секунд. Но, как мы видели, она принимает лишь целое число секунд, что делает невозможным задержки на короткие периоды, она потенциально может также взаимодействовать с обработчиками
SIGALRM
. Функция
nanosleep
компенсирует эти недостатки:

Поделиться:
Популярные книги

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

Прорыв

Круз Андрей
3. Эпоха мертвых
Фантастика:
боевая фантастика
9.33
рейтинг книги
Прорыв

Седина в бороду, Босс… вразнос!

Трофимова Любовь
Юмор:
юмористическая проза
5.00
рейтинг книги
Седина в бороду, Босс… вразнос!

Медиум

Злобин Михаил
1. О чем молчат могилы
Фантастика:
фэнтези
7.90
рейтинг книги
Медиум

Я не царь. Книга XXIV

Дрейк Сириус
24. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не царь. Книга XXIV

Чужак из ниоткуда 3

Евтушенко Алексей Анатольевич
3. Чужак из ниоткуда
Фантастика:
космическая фантастика
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 3

Артефактор. Шаг в неизвестность

Седых Александр Иванович
1. Артефактор
Фантастика:
фэнтези
боевая фантастика
попаданцы
6.12
рейтинг книги
Артефактор. Шаг в неизвестность

Сотник

Ланцов Михаил Алексеевич
4. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Сотник

Убивать чтобы жить 6

Бор Жорж
6. УЧЖ
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 6

Я Гордый часть 7

Машуков Тимур
7. Стальные яйца
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Я Гордый часть 7

Третий Генерал: Тома I-II

Зот Бакалавр
1. Третий Генерал
Фантастика:
городское фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Третий Генерал: Тома I-II

Телохранитель Генсека. Том 4

Алмазный Петр
4. Медведев
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Телохранитель Генсека. Том 4

Хозяин Стужи 6

Петров Максим Николаевич
6. Злой Лед
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Хозяин Стужи 6

Вперед в прошлое 2

Ратманов Денис
2. Вперед в прошлое
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Вперед в прошлое 2