epoll和超时

时间:2012-05-27 06:56:47

标签: c events epoll

我正在使用epoll来管理大约20到30个套接字。我发现epoll_wait可以用来等待一些数据到达其中一个套接字,但我不知道如何在套接字级别实现超时。我可以在epoll_wait上使用超时但在我的情况下它不是很有用。例如,如果我需要关闭一个未记录活动的套接字>无论如何,500 ms orr可以每隔200 ms向套接字发送一些数据。如何使用epoll实现这些套接字级超时?任何建议和想法将不胜感激!

谢谢, Shivam Kalra

2 个答案:

答案 0 :(得分:4)

听起来你正在尝试编写一个事件循环(如果有的话,请查看libev btw)。 epoll无法帮助您,您必须自己跟踪套接字不活动(例如clock_gettime()gettimeofday()),然后每秒唤醒几次并检查您需要的所有内容。< / p>

一些伪代码

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

如果所有套接字都处于非活动状态,这将使您每秒唤醒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 */
        ...
    }
}

其中diff()为您提供2 struct timeval s和now()的差异,为您提供当前时间戳。

答案 1 :(得分:4)

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

如果计时器到期(因为套接字已经处于非活动状态500ms),那么计时器将在epoll对象中变为“read ready”,并导致等待EPOLL_CTL_ADD的任何线程被唤醒。然后该线程可以处理计时器相关套接字的超时。