2014-09-12 3 views
1

Я создал таймер, используя функцию POSIX timerfd. Намерение, таймер должен быть периодическим, и истечение таймера наблюдается с отдельной функции, называемой myFunc()Почему мой таймер не периодический, но истек только один раз?

Я называю эту функцию несколько раз, так что истечение таймера можно наблюдать периодически после ожидания 5 секунд.

Проблема заключается в том, что, как только первый раз она истекает через 5 секунд, в следующий раз и далее ... она не истекает снова, то есть без задержки в 5 секунд наблюдается со второй итерации вперед.

Может ли кто-нибудь сказать мне, что мне не хватает?

#include <stdio.h> 
#include <iostream> 
#include <errno.h> 
#include <dlfcn.h> 
#include <assert.h> 
#include <sys/mman.h> 
#include <new> 

#include <limits.h> 
#include <sys/epoll.h> 
#include <sys/timerfd.h> 

using namespace std; 

struct epoll_event event; 
int timer_fd, efd, no_of_fd; 
void myFunc(int i); 

int main() 
{ 
    struct itimerspec its; 

    its.it_value.tv_sec = 5; 
    its.it_value.tv_nsec = 0; 

    its.it_interval.tv_sec = 3; // Every 3 seconds interval 
    its.it_interval.tv_nsec = 0; 


    efd = epoll_create(2); 
    timer_fd = timerfd_create(CLOCK_REALTIME, TFD_NONBLOCK); 

    if (timer_fd == -1) 
    { 
    fprintf(stderr, "timerfd_create error in start timer"); 
    return 1; 
    } 

    event.data.fd = timer_fd; 
    event.events = EPOLLIN|EPOLLPRI; 

    if (epoll_ctl(efd, EPOLL_CTL_ADD, timer_fd, &event) == -1) 
    { 
    fprintf(stderr, "epoll_ctl error in start timer"); 
    return 1; 
    } 

    if (timerfd_settime(timer_fd, 0, &its, NULL) == -1) 
    { 
    fprintf(stderr, "timerfd_settime error in start timer"); 
    return 1; 
    } 
    myFunc(10); 
    myFunc(20); 
    myFunc(30); 
} 

void myFunc(int i) 
{ 
    printf("Inside myFunc %d\n", i); 
    no_of_fd = 0; 
    struct epoll_event revent; 
    errno = 0; 
    do { 
    no_of_fd = epoll_wait(efd, &revent, 1, -1); 
    } while (no_of_fd < 0 && errno == EINTR); 

    if (no_of_fd < 0) 
    { 
    fprintf(stderr, "epoll_wait error in start timer"); 

    } 

    if (revent.data.fd == timer_fd) { 
    printf("Timer expired \n");  
    } 

} 
+0

Ладно, я получил небольшой обходной путь, используя механизм с запуском по фронту, который я использую: 'event.events = EPOLLIN | EPOLLPRI | EPOLLET;' и каждый раз мне нужно для чтения дескриптора файла всякий раз, когда происходит тайм-аут, и он повторяется. Но не может ли он использоваться с помощью механизма с запуском уровня? – kingsmasher1

+0

Хорошо, я получил решение: он работает и с уровнем срабатывания, и при условии, что я читаю данные, полученные каждый раз, он повторяется. У любого есть какая-то подсказка, сколько байтов должно быть прочитано каждый раз или какое минимальное количество байтов для чтения, чтобы оно работало? – kingsmasher1

ответ

0

При использовании epoll с уровня запуска, вы должны прочитать 8 байт на каждом EPOLLIN. Это int64, который сообщает вам количество выходов событий. Чтение его эффективно «очищает» это число, так что следующий EPOLLIN является результатом истечения другого события.

Пособие рассказывает о чтении:

  If the timer has already expired one or more times since its 
      settings were last modified using timerfd_settime(), or since 
      the last successful read(2), then the buffer given to read(2) 
      returns an unsigned 8-byte integer (uint64_t) containing the 
      number of expirations that have occurred. (The returned value 
      is in host byte order—that is, the native byte order for 
      integers on the host machine.) 
Смежные вопросы