2015-02-11 1 views
0

Я искал ответ для this question, и я натолкнулся на функции timerfd_create и epoll в Linux. В учебном пособии было сказано, что epoll_ctl() имеет член объединения структуры epoll_event, который может использоваться для выполнения функции callback при запуске события timerfd. Но я не уверен, как это сделать. Кто-нибудь может помочь.Как передать указатель функции обратного вызова в структуру epoll_event в C++

+0

Вы имеете в виду 'epoll_wait', или у вас есть' timerfd', который срабатывает? – Barry

+0

У меня есть timerfd, который создает таймер, и этот таймер истекает. – Jackzz

ответ

3

Вы не можете поместить указатель на функцию обратного вызова в epoll_event, потому что он не может поместиться в любой из этих слотов:

typedef union epoll_data { 
    void  *ptr; 
    int   fd; 
    uint32_t  u32; 
    uint64_t  u64; 
} epoll_data_t; 

Что вы могли бы сделать вместо этого хранить ФД таймера в epoll_event и проверить увидеть, если это тот, который стреляет:

epoll_event ev; 
ev.data.fd = timerfd; 

epoll_ctl(epollfd, EPOLL_CTL_ADD, timerfd, &ev); 

с этой установки, а затем, когда мы называем epoll_wait, мы можем проверить, если event что уволен был за timerfd:

int n = epoll_wait (epollfd, events , num_events, -1); 
for (int i = 0; i < n; ++i) { 
    if (events[i].data.fd == timerfd) { 
     handle_timer_callback(); 
    } 
    else { 
     // something else 
    } 
} 

В качестве альтернативы, если вы открыты для давая некоторую работу, вы можете просто создать полную иерархию объектов для событий:

class EventHandler { 
public: 
    virtual ~EventHandler() = default; 
    virtual int fd() const = 0; 
    virtual void fire() = 0; 
}; 

Вы можете хранить EventHandler* в ptr:

EventHandler* handler = new TimerHandler(); 
ev.data.ptr = handler; 
epoll_ctl(epollfd, EPOLL_CTL_ADD, handler->fd(), &ev); 

И так, если все мы помещаем в epoll является EventHandler:

int n = epoll_wait (epollfd, events , num_events, -1); 
for (int i = 0; i < n; ++i) { 
    static_cast<EventHandler*>(events[i].data.ptr)->fire(); 
} 
+0

Это не тайм-аут эпохи. – Jackzz

+0

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

+0

Спасибо за помощь. Но можете ли вы дать минимальный рабочий пример? Я до сих пор не использовал ни одну из этих функций и немного смущен. Извините, если эта необходимость бесполезна. – Jackzz