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

发布于 2024-11-09 06:43:30 字数 1594 浏览 0 评论 0原文

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

问题是,我使用 epoll_wait 等待文件描述符,然后使用 fd=revent.data.fdfd=timer_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?
}

}

I have a program which creates a timer using timerfd_create (the timer when it expires, sets a file descriptor).

Problem is, i am using epoll_wait to wait for the file descriptor, then checking for the expiration using fd=revent.data.fd and fd=timer_fd (see program below).

But if i do this, epoll_wait blocks my program till timer expires, and i don't want this to happen..i want the program to run, and periodically i will check for timer expire. Is there any alternative approach to that?

Please see the program below.

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?
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怎樣才叫好 2024-11-16 06:43:30

由于您只等待一个计时器,因此您可以通过读取来检查它是否过期,而不是使用 epoll 进行轮询。然后,它已过期的次数将存储在您正在读取的缓冲区中,或者如果它尚未过期,读取将失败并显示错误再次出现。

// 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_NONBLOCK 标志初始化 timer_fd,否则如果 read 尚未过期,则读取将被阻止,而不是失败了,但你已经这么做了。

Instead of polling with epoll, since you're only waiting on one timer you can just check if it's expired by reading it. The number of times it has expired will then be stored in the buffer that you're reading into, or if it hasn't expired, the read will fail with the error 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);
}

Note that you'll need to initialize timer_fd with the flag TFD_NONBLOCK, or else the read will block if it hasn't expired yet rather than fail, but you already do that.

挥剑断情 2024-11-16 06:43:30

这看起来相当倒退。首先创建timerfd的原因是为了允许轮询fd以获取计时器完成情况,而不是像普通timer_create接口允许的那样使用信号/线程/{无通知}。如果您不想轮询 fd,请不要使用timerfd_create!

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

This seems quite backwards. The reason why timerfd was created in the first place was to allow polling a fd for timer completions instead of using signals/threads/{no notification} as the normal timer_create interface allows you. If you don't want to poll on a fd, don't use timerfd_create!

So if you want to periodically poll your timer yourself, just use timer_create() to create a timer with SIGEV_NONE, and then use timer_gettime() to check it manually.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文