我正在使用epoll来管理大约20到30个套接字。我发现epoll_wait可以用来等待一些数据到达其中一个套接字,但我不知道如何在套接字级别实现超时。我可以在epoll_wait上使用超时但在我的情况下它不是很有用。例如,如果我需要关闭一个未记录活动的套接字>无论如何,500 ms orr可以每隔200 ms向套接字发送一些数据。如何使用epoll实现这些套接字级超时?任何建议和想法将不胜感激!
谢谢, Shivam Kalra
答案 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
的任何线程被唤醒。然后该线程可以处理计时器相关套接字的超时。