epoll和超时

Shi*_*vam 2 c events epoll

我正在使用epoll管理约20到30个套接字。我发现epoll_wait可以用于等待一些数据通过套接字之一到达,但是我错过了如何在套接字级别实现超时。我可以在epoll_wait上使用超时,但是对于我来说不是很有用。例如,如果我需要每次关闭一个套接字,而在该套接字中没有记录任何活动,时间超过500毫秒,那么无论如何,orr可能每200毫秒将一些数据发送到套接字。如何使用epoll实现这些套接字级别的超时?任何建议和想法将不胜感激!

谢谢,Shivam Kalra

Cra*_*urg 6

尝试将每个套接字与计时器 fd 对象 ( timerfd_create)配对。对于应用程序中的每个套接字,创建一个最初设置为在 500 毫秒后到期的计时器并将计时器添加到 epoll 对象(与套接字相同——viaepoll_ctlEPOLL_CTL_ADD)。然后,每当数据到达套接字时,将该套接字的关联计时器重置回 500 毫秒超时。

如果计时器到期(因为套接字已处于非活动状态 500 毫秒),则计时器将在 epoll 对象中变为“读取就绪”并导致任何等待epoll_wait唤醒的线程。然后该线程可以处理计时器关联套接字的超时。


hro*_*tyr 5

听起来您正在尝试编写事件循环(如果这样,请查看libev btw)。 epoll不会帮你那里,你必须跟踪插座闲置自己(的clock_gettime()gettimeofday()为实例),然后醒来好几次,你需要一秒钟,检查一切。

一些伪代码

while (1) {
    n = epoll_wait(..., 5);
    if (n > 0) {
        /* process activity */
    } else {
        /* process inactivity */
    }
}
Run Code Online (Sandbox Code Playgroud)

如果所有套接字都不活动,这将每秒唤醒您200次。

不活动检查需要检查套接字列表以及最后一个不活动的时间戳:

struct sockstamp_s {
    /* socket descriptor */
    int sockfd;
    /* last active */
    struct timeval tv;
};

/* check which socket has been inactive */
for (struct sockstamp_s *i = socklist; ...; i = next(i)) {
    if (diff(s->tv, now()) > 500) {
        /* socket s->sockfd was inactive for more than 500 ms */
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里diff(),您可以得到2 struct timevals now()的时间差,并为您提供当前时间戳。