Страницы

Поиск по вопросам

среда, 12 июня 2019 г.

Как реализовать таймер с асинхронным вызовом?

Интересует как реализовать таймер с асинхронным вызовом через промежуток времени на си. Вот, допустим, таймер на javascript задается:
setTimeout(func, 1000);
или на boost::asio:
boost::asio::deadline_timer t(io, boost::posix_time::seconds(5)); t.async_wait(&print);
Интересует как такое же реализовать на си. Т.е. задаем таймер, делаем полезную работу, а через некоторое время срабатывает сигнал или как-то по-другому асинхронно оповещаем. Просто тупо делать задержку это не то, а именно вызвать через какой-то промежуток времени, не приостанавливая работу до этого момента. Хотя бы сам принцип, что использовать, eventfd, сигналы или что-то еще.


Ответ

Вы правильно думаете, используйте сигналы, вызванные с помощью alarm() или setitimer(). Системный вызов setitimer() является обобщением вызова alarm()
/* Обработчик сигнала*/ void catch_alarm(int sig) { printf("Do stuff..."); }
/* Устанавливаем обработчик для SIGALRM */ signal (SIGALRM, catch_alarm);
/* Ставим таймер на 2 секунды */ alarm(2);
Вообще, каждый процесс имеет три независимых таймера:
Таймер реального времени, отсчитывающий прошедшее время. Этот таймер отправляет сигнал SIGALRM процессу, когда он истекает. Виртуальный таймер, который измеряет только время выполнения самого процесса. Этот таймер отправляет сигнал SIGVTALRM процессу, когда он истекает. Таймер профилирования, который измеряет время выполнения самого процесса и время, проведённое в ожидании завершения системных вызовов. Этот таймер отправляет сигнал SIGPROF процессу, когда он истекает.
Вы можете установить только один таймер каждого типа в любой момент времени. Если вы установите таймер, который еще не истек, этот таймер просто сбрасывается на новое значение.

Комментариев нет:

Отправить комментарий