我使用epoll來管理大約20到30個套接字。我發現epoll_wait可以用來等待一些數據到達其中一個套接字,但我錯過了如何在套接字級別實現超時。我可以在epoll_wait上使用超時,但在我的情況下它不是很有用。例如,如果我需要每關閉一個沒有記錄活動的套接字> 500毫秒,orr可能會每200毫秒發送一些數據到套接字,無論如何。這些套接字級別超時如何使用epoll實現?任何建議和想法,將不勝感激!epoll和超時
感謝, Shivam卡爾拉
我使用epoll來管理大約20到30個套接字。我發現epoll_wait可以用來等待一些數據到達其中一個套接字,但我錯過了如何在套接字級別實現超時。我可以在epoll_wait上使用超時,但在我的情況下它不是很有用。例如,如果我需要每關閉一個沒有記錄活動的套接字> 500毫秒,orr可能會每200毫秒發送一些數據到套接字,無論如何。這些套接字級別超時如何使用epoll實現?任何建議和想法,將不勝感激!epoll和超時
感謝, Shivam卡爾拉
聽起來你想要寫一個事件循環(如果有的話看看libev BTW)。 epoll
不會幫助你,你必須自己跟蹤套接字的不活動情況(例如,clock_gettime()
或gettimeofday()
),然後每秒醒來幾次並檢查所需的一切。
一些僞代碼
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()
給你當前的時間戳。
嘗試將每個套接字與計時器fd對象配對(timerfd_create
)。對於應用程序中的每個套接字,創建一個初始設置爲在500ms後過期的定時器,然後將定時器添加到epoll對象(與套接字通過epoll_ctl
和EPOLL_CTL_ADD
相同)。然後,每當數據到達套接字時,將該套接字的關聯定時器重置爲500毫秒超時。
如果定時器到期(因爲套接字已經不活動500ms),那麼定時器將在epoll對象中變爲「已準備就緒」,並導致任何等待epoll_wait
的線程喚醒。然後該線程可以處理定時器關聯套接字的超時。
感謝您的回覆。但是,我想知道,如果我可以使用epoll等待非常短的時間可以約10毫秒的無活動檢查?與select + inactivity chec相比,我能獲得任何性能改進嗎? – Shivam
取決於你越會喚醒你消耗的CPU越多。而且,你需要一個1000 HZ的內核來喚醒每一毫秒。就像我說的那樣,我強烈建議一個準備好的事件循環(像libev或libevent),它們針對這些情況進行了優化(以依賴關係爲代價)。 – hroptatyr