C epoll_wait的替代方案,它不等待文件描述符?

C epoll_wait的替代方案,它不等待文件描述符?,c,linux,file,epoll,C,Linux,File,Epoll,我有一个程序,它使用timerfd_create创建一个计时器(计时器过期时,设置一个文件描述符) 问题是,我正在使用epoll\u wait等待文件描述符,然后使用fd=revent.data.fd和fd=timer\u fd检查过期时间(请参阅下面的程序) 但如果我这样做,epoll\u wait会阻止我的程序,直到计时器过期,我不希望发生这种情况。我希望程序运行,并定期检查计时器是否过期。有没有其他办法 请看下面的节目 enter code here #include <sys/ti

我有一个程序,它使用timerfd_create创建一个计时器(计时器过期时,设置一个文件描述符)

问题是,我正在使用
epoll\u wait
等待文件描述符,然后使用
fd=revent.data.fd
fd=timer\u fd
检查过期时间(请参阅下面的程序)

但如果我这样做,
epoll\u 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?
}
在此处输入代码
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
结构itimerspec its;
结构epoll_事件,revent;
int timer_fd、efd、fd1、fd2;
/*设置计时器间隔*/
its.it\u interval.tv\u sec=1;
its.it\u interval.tv\u nsec=0;
/*设置计时器过期时间*/
其.it_值.tv_sec=5;
它的.it\u值.tv\u nsec=0;
efd=epoll_create(2);
timer\u fd=timerfd\u创建(时钟实时,TFD\u非块);
event.data.fd=计时器\u fd;
event.events=EPOLLIN | EPOLLPRI;
epoll\u ctl(efd、epoll\u ctl\u ADD、timer\u fd和event);
如果(计时器\u fd==-1)
{
fprintf(标准,“timerfd_设置时间错误:”);
出口
}
if(timerfd_settime(timer_fd,0,&its,NULL)=-1)
{
fprintf(标准,“timerfd_设置时间错误:”);
出口
}
printf(“启动计时器…”);
fd1=epoll_wait(efd和revent,1,-1);

if(fd1而不是使用epoll进行轮询,因为您只等待一个计时器,所以您可以通过读取它来检查它是否过期。它过期的次数将存储在您正在读取的缓冲区中,或者如果它没有过期,
读取
将失败并显示错误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);
}

请注意,您需要使用标志
TFD\u NONBLOCK
初始化
timer\u fd
,否则
读取的
将在尚未过期时被阻止,而不是失败,但您已经这样做了。

这似乎是非常倒退的。创建timerfd的原因首先是为了允许轮询fd以在不要使用signals/threads/{no notification}作为正常的timer\u create接口。如果您不想在fd上轮询,请不要使用timerfd\u create


因此,如果您想自己定期轮询计时器,只需使用timer_create()创建一个带有SIGEV_NONE的计时器,然后使用timer_gettime()手动检查。

@Sean:为什么uint64\u t?我们不能直接使用int吗?它给出了一个错误
timerfd1.c:59:error:'for'循环初始声明在C99模式之外使用
不,事实上。从计时器读取数据非常挑剔——如果给它一个小于8字节的缓冲区,它在任何情况下都会失败。我没有测试代码I posted所以它可能无法按原样工作,但您发布的错误似乎不是由此产生的。您是否在任何地方都有类似的
for(int i=0;i
?在老式的C语言中,您不能这样做,您必须执行
int i;for(i=0;i
@Sean:Ohh是的,非常感谢……原因也是如此……而且你的代码也有效,非常感谢:)