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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

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
компенсирует эти недостатки:

#include <time.h> /* POSIX ТМР */

int nanosleep(const struct timespec *req, struct timespec *rem);

Эта функция является частью необязательного расширения POSIX «Таймеры» (TMR). Два аргумента являются запрошенным временем задержки и оставшимся числом времени в случае раннего возвращения (если

rem
не равен
NULL
). Оба являются значениями
struct timespec
:

struct timespec {

 time_t tv_sec; /* секунды */

 long tv_nsec; /* наносекунды */

};

Значение

tv_nsec
должно быть в диапазоне от 0 до 999 999 999. Как и в случае со
sleep
, время задержки может быть больше запрошенного в зависимости оттого, когда и как ядро распределяет время для исполнения процессов.

В отличие от

sleep
,
nanosleep
не взаимодействует ни с какими сигналами, делая ее более безопасной и более простой для использования.

Возвращаемое значение равно 0, если выполнение процесса было задержано в течение всего указанного времени. В противном случае оно равно -1, с

errno
, указывающим ошибку. В частности, если
errno
равен
EINTR
,
nanosleep
была прервана сигналом. В этом случае, если
rem
не равен
NULL
,
struct timespec
, на которую она указывает, содержит оставшееся время задержки. Это облегчает повторный вызов
nanosleep
для продолжения задержки.

Хотя это выглядит немного странным, вполне допустимо использовать одну и ту же структуру для обоих параметров:

struct timespec sleeptime = /* что угодно */;

int ret;

ret = nanosleep(&sleeptime, &sleeptime);

struct timeval
и
struct timespec
сходны друг с другом, отличаясь лишь компонентом долей секунд. Заголовочный файл GLIBC
<sys/time.h>
определяет для их взаимного преобразования друг в друга два полезных макроса:

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

Третий. Том 4

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
Третий. Том 4

Сирийский рубеж 3

Дорин Михаил
7. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 3

Государь

Кулаков Алексей Иванович
3. Рюрикова кровь
Фантастика:
мистика
альтернативная история
историческое фэнтези
6.25
рейтинг книги
Государь

Законы Рода. Том 5

Мельник Андрей
5. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 5

Сильнейший Столп Империи. Книга 2

Ермоленков Алексей
2. Сильнейший Столп Империи
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Сильнейший Столп Империи. Книга 2

Позывной "Князь" 3

Котляров Лев
3. Князь Эгерман
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Позывной Князь 3

Изгой Проклятого Клана. Том 4

Пламенев Владимир
4. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Изгой Проклятого Клана. Том 4

Технарь

Муравьёв Константин Николаевич
1. Технарь
Фантастика:
космическая фантастика
попаданцы
7.13
рейтинг книги
Технарь

Воин

Бубела Олег Николаевич
2. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.25
рейтинг книги
Воин

По осколкам твоего сердца

Джейн Анна
2. Хулиган и новенькая
Любовные романы:
современные любовные романы
5.56
рейтинг книги
По осколкам твоего сердца

Первый среди равных

Бор Жорж
1. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных

Двойник Короля 2

Скабер Артемий
2. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Двойник Короля 2

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4