我有一个程序使用timerfd_create(计时器到期时,设置文件描述符)创build一个计时器。
问题是,我正在使用epoll_wait
等待文件描述符,然后使用fd=revent.data.fd
和fd=timer_fd
(请参阅下面的程序)检查到期fd=revent.data.fd
。
但是,如果我这样做, epoll_wait
阻止我的程序,直到计时器到期,我不希望这种情况发生..我希望程序运行,并定期我会检查计时器到期。 有没有其他办法呢?
请参阅下面的程序。
enter code here #include <sys/timerfd.h> #include <sys/time.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/epoll.h> #include <time.h> int main() { struct itimerspec its; struct epoll_event event, revent; int timer_fd, efd, fd1, fd2; /* Setting timer interval */ its.it_interval.tv_sec=1; its.it_interval.tv_nsec=0; /* Setting timer expiration */ its.it_value.tv_sec=5; its.it_value.tv_nsec=0; efd=epoll_create(2); timer_fd=timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); event.data.fd=timer_fd; event.events=EPOLLIN|EPOLLPRI; epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event); if(timer_fd==-1) { fprintf(stderr,"timerfd_settime error:"); exit; } if(timerfd_settime(timer_fd, 0, &its, NULL)==-1) { fprintf(stderr,"timerfd_settime error:"); exit; } printf("Starting the timer..."); fd1=epoll_wait(efd, &revent, 1, -1); if(fd1<0) { fprintf(stderr, "epoll_wait error\n"); exit; } else { fprintf(stdout, "number of fds: %d",fd1); } fd2=revent.data.fd; if(fd2==timer_fd) { printf("Timer expired\n"); // IMPORTANT: This i want to check periodically without epoll_wait which blocks the program, What is the alternative? }
}
由于您只是在等待一个计时器,您可以通过read
它来检查是否过期,而不是使用epoll进行轮询。 过期的次数将被存储在read
入的缓冲区中,或者如果没有过期,则read
将失败并返回错误EAGAIN。
// set up timer // ... uint64_t expirations; if ((read(timer_fd, &expirations, sizeof(uint64_t))==-1) && errno == EAGAIN) { printf("Timer has not expired yet.\n"); } else { printf("Timer has expired %llu times.\n", expirations); }
请注意,您需要使用timer_fd
标志初始化timer_fd
,否则read
将会阻塞(如果尚未过期而不是失败),但您已经这样做了。
这似乎很倒退。 timerfd首先被创建的原因是允许轮询一个fd的定时器完成,而不是使用signals / threads / {not notification},因为正常的timer_create接口允许你。 如果您不想在fd上进行轮询,请不要使用timerfd_create!
所以如果你想周期性地轮询你的计时器,只需使用timer_create()来创建一个SIGEV_NONE的计时器,然后使用timer_gettime()来手动检查它。