Альтернатива epoll_wait, которая не ждет файлового дескриптора? - PullRequest
2 голосов
/ 23 мая 2011

У меня есть программа, которая создает таймер с помощью timerfd_create (таймер, когда он истекает, устанавливает дескриптор файла).

Проблема в том, что я использую epoll_wait для ожидания дескриптора файла, а затем проверяю срок действия, используя fd=revent.data.fd и fd=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?
}

}

Ответы [ 2 ]

2 голосов
/ 23 мая 2011

Вместо опроса с epoll, так как вы ожидаете только один таймер, вы можете просто проверить, истек ли он, read используя его.Количество истекших периодов будет сохранено в буфере, в который вы 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 с флагом TFD_NONBLOCK, иначе read заблокируется, если срок его действия еще не истек, а не произошел сбой, но вы уже это делаете.

1 голос
/ 24 мая 2011

Это выглядит довольно задом наперед.Причина, по которой timerfd был создан в первую очередь, заключалась в том, чтобы разрешить опрос fd для завершения таймера вместо использования сигналов / потоков / {никаких уведомлений}, как позволяет обычный интерфейс timer_create.Если вы не хотите опрашивать fd, не используйте timerfd_create!

Так что, если вы хотите периодически опрашивать свой таймер самостоятельно, просто используйте timer_create (), чтобы создать таймер с SIGEV_NONE, а затем используйтеtimer_gettime () чтобы проверить это вручную.

...