如何在 C++ 中将回调函数指针传递给 epoll_event 结构
How to pass a callback function pointer to epoll_event structure in C++
我一直在寻找 this question 的答案,我在 Linux 中找到了函数 timerfd_create
和 epoll
。在一个教程中,据说 epoll_ctl()
有一个 epoll_event
结构的 epoll_data_t
联合成员,可用于在 timerfd
事件上执行 callback
函数射击。但我不确定该怎么做。谁能帮帮忙。
您不能将回调函数指针放入 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();
}
我一直在寻找 this question 的答案,我在 Linux 中找到了函数 timerfd_create
和 epoll
。在一个教程中,据说 epoll_ctl()
有一个 epoll_event
结构的 epoll_data_t
联合成员,可用于在 timerfd
事件上执行 callback
函数射击。但我不确定该怎么做。谁能帮帮忙。
您不能将回调函数指针放入 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();
}