Я использую таймер, используя timerfd. Это относительный таймер, который мне просто нужно повторять навсегда с той скоростью, на которую он установлен. Я хочу опросить это событие и изначально попытался использовать опрос. Когда я это сделал, я увижу событие таймера в первый раз, а затем больше никогда. Однако, когда я перешел на использование epoll (никаких изменений вообще не было в настройке timerfd), он работает так, как ожидалось.Повторяющееся событие timerfd работает с epoll, а не с опросом
Вот код с опросом:
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
int main(int ac, char *av[])
{
struct pollfd p;
int timerfd;
struct itimerspec timerValue;
/* clear pollfd */
bzero(&p, sizeof(p));
/* set timerfd */
timerfd = timerfd_create(CLOCK_REALTIME, 0);
if (timerfd < 0) {
printf("failed to create timer fd\n");
exit(1);
}
bzero(&timerValue, sizeof(timerValue));
timerValue.it_value.tv_sec = 1;
timerValue.it_value.tv_nsec = 0;
timerValue.it_interval.tv_sec = 1;
timerValue.it_interval.tv_nsec = 0;
/* set events */
p.fd = timerfd;
p.revents = 0;
p.events = POLLIN;
/* start timer */
if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
printf("could not start timer\n");
exit(1);
}
/* wait for events */
while (1) {
int numEvents = poll(&p, 1, -1);
if (numEvents > 0) {
int timersElapsed = 0;
(void) read(p.fd, &timersElapsed, 8);
printf("timers elapsed: %d\n", timersElapsed);
}
}
exit(0);
}
А вот код с Epoll:
#include <sys/timerfd.h>
#include <sys/poll.h>
#include <sys/epoll.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
int main(int ac, char *av[])
{
struct epoll_event epollEvent;
struct epoll_event newEvents;
int timerfd;
int epollfd;
struct itimerspec timerValue;
/* set timerfd */
timerfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (timerfd < 0) {
printf("failed to create timer fd\n");
exit(1);
}
bzero(&timerValue, sizeof(timerValue));
timerValue.it_value.tv_sec = 1;
timerValue.it_value.tv_nsec = 0;
timerValue.it_interval.tv_sec = 1;
timerValue.it_interval.tv_nsec = 0;
/* set events */
epollfd = epoll_create1(0);
epollEvent.events = EPOLLIN;
epollEvent.data.fd = timerfd;
epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &epollEvent);
/* start timer */
if (timerfd_settime(timerfd, 0, &timerValue, NULL) < 0) {
printf("could not start timer\n");
exit(1);
}
/* wait for events */
while (1) {
int numEvents = epoll_wait(epollfd, &newEvents, 1, 0);
if (numEvents > 0) {
int timersElapsed = 0;
(void) read(epollEvent.data.fd, &timersElapsed, 8);
printf("timers elapsed: %d\n", timersElapsed);
}
}
exit(0);
}
Любая идея, что я могу делать неправильно с опросом? Может быть, он не предназначен для использования таким образом с timerfd? Спасибо.
Ваш код poll() отлично подходит для меня. Попробуйте найти что-нибудь подозрительное, когда вы запускаете код с помощью инструмента strace. – nos
Я тоже пробовал ваше cdoe, и он отлично работает. Я запускал его на Linux 3.13. –
@ nos - Я запускал свой код poll() с помощью strafe, и проблема в том, что дескриптор файла poll() меняется во втором вызове. Таким образом, первый вызов poll() вызывается, значение fd равно 3 (это было создано timer_createfd). Однако во второй раз, когда он вызывается, значение fd равно 0. 'poll ([{fd = 3, events = POLLIN}], 1, 4294967295) = 1 ([{fd = 3, revents = POLLIN}]). .. poll ([{fd = 0, events = POLLIN}], 1, 4294967295 ... блоки навсегда'. – budhe888