c++ - 如何在 C++ 中将回调函数指针传递给 epoll_event 结构

标签 c++ linux timer callback epoll

我一直在寻找 this question 的答案我遇到了 Linux 中的函数 timerfd_createepoll。在一个教程中说 epoll_ctl() 有一个 epoll_data_t union 成员 epoll_event 结构可以用来执行一个 timerfd 事件触发的回调 函数。但我不确定该怎么做。谁能帮忙。

最佳答案

您不能将回调函数指针放入 epoll_event 中,因为它不适合这些槽中的任何一个:

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

您可以做的是将计时器 fd 存储在 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();
}

关于c++ - 如何在 C++ 中将回调函数指针传递给 epoll_event 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28446631/

相关文章:

C# - Windows 服务中的多个计时器

node.js - 如何将一个永远启动的 nodejs 应用程序带到前台?

Android Lollipop 定时器(持续时间)输入

c++ - 在嵌套循环/循环不变量中检查一次

c++ - 使用 pugixml 解释程序的内存消耗

c++ - VS2010中如何设置相对路径

c++ - Windows:处理所有线程中的段错误

linux - 无法终止 fork 进程

linux - BASH-查找相同大小的文件,使用 cksum,删除 dupe 但保留其名称作为符号链接(symbolic link)

javascript - clearTimeout 动态更新定时器