Why waiting indefinitely - timerfd_create? Where have i gone wrong?
I have created a timer which can expire, in 5 seconds using timerfd_create
, but i can see that it is waiting indefinitely.
Can someone help me?
Thanks in advance.
Here is my code:
enter code here
#include <sys/timerfd.h>
#include <sys/time.h>
#include &l开发者_开发知识库t;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;
/* 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);
event.data.fd=timer_fd;
event.events=EPOLLIN;
epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event);
timer_fd=timerfd_create(CLOCK_REALTIME, 0);
if(timer_fd==-1)
{
perror("timerfd:");
}
if(timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &its, NULL)==-1)
{
perror("timerfd_settime error:");
}
printf("Starting the timer...");
while(1) {
epoll_wait(efd, &revent, 1, -1);
}
}
Reverse the order of calls to epoll_ctl
and timerfd_create
. Right now you are adding some random integer value to the event set.
Edit 0:
Several points:
timerfd_create(2)
produces a file descriptor, just likeopen(2)
orsocket(2)
. You have to assign the return value to thetimer_fd
variable before giving it to theepoll_ctl(2)
, otherwise it's just a random integer value from the stack.- Don't use
TFD_TIMER_ABSTIME
- you are asking the kernel to start a timer that expires one second after the Epoch (which is not that big of a deal - it'll just expire immediately). - When the timer expires
epoll_wait(2)
returns the number of ready file descriptors,1
in your example, and you are expected to handle that. You, on the other hand, just ignore that return value and spin around in a tight loop, so you don't even know the timer is expiring. - You need to read from timer file descriptor to consume the expiration event. Otherwise all subsequent calls to
epoll_wait(2)
will just return immediately since the descriptor remains in the "signaled" state. - Always check the return values of the system calls and handle error conditions based on the value of
errno(3)
- manual page for each call gives you possible error values.
Edit 1:
You do want a loop around the epoll_wait(2)
(or select(2)
. or poll(2)
), but you need:
- handle the IO events being signaled (that's the whole point of these multiplexing APIs - being able to wait on multiple descriptors and dispatch the events), and
- be able to break out of that loop (on a signal, on input from a dedicated file descriptor ala self-pipe trick, or on some application event).
Hope this helps.
精彩评论