2012-05-27 2 views
2

epoll을 사용하여 약 20 ~ 30 개의 소켓을 관리하고 있습니다. epoll_wait는 소켓 중 하나를 통해 도착할 데이터를 기다리는 데 사용할 수 있지만 소켓 레벨에서 시간 제한을 구현하는 방법은 무엇인지 알 수 없습니다. epoll_wait에서 타임 아웃을 사용할 수는 있지만 내 경우에는별로 유용하지 않습니다. 예를 들어, 500ms 이상 동안 활동이 기록되지 않은 모든 소켓을 닫을 필요가 있다면 orr은 200ms마다 어떤 데이터를 소켓으로 보낼 수 있습니다. epoll을 사용하여 소켓 레벨 타임 아웃을 어떻게 구현할 수 있습니까? 모든 제안과 아이디어는 인정 될 것입니다!epoll 및 제한 시간

감사합니다, 당신이 (그래서 BTW libev 살펴있는 경우) 이벤트 루프를 작성하려는처럼 Shivam Kalra

답변

4

는 소리. 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() 당신이 struct timeval의 차이를 제공하고 now() 당신에게 현재의 타임 스탬프를 제공합니다.

+0

답장을 보내 주셔서 감사합니다. 하지만, 매우 짧은 시간 동안 epoll 대기 상태로 비활성 점검을 사용할 수 있다면 약 10ms가 걸릴지 궁금합니다. select + inactivity chec보다 성능이 향상 되었습니까? – Shivam

+0

의존할수록 더 많이 소비하는 CPU를 깨울 수 있습니다. 또한 밀리 초마다 깨우려면 1000 HZ 커널이 필요합니다. 앞서 말했듯이, 나는 상황에 최적화 된 의존성 (dependency)의 가격으로 준비된 이벤트 루프 (libev 또는 libevent와 같은)를 제안한다. – hroptatyr

3

각 소켓을 타이머 fd 개체 (timerfd_create)와 쌍으로 연결해보십시오. 응용 프로그램의 각 소켓에 대해 처음에 500ms 후에 만료되도록 설정 한 타이머를 만들고 타이머를 epoll 객체에 추가하십시오 (소켓 비아 epoll_ctlEPOLL_CTL_ADD과 동일). 그런 다음 데이터가 소켓에 도착할 때마다 해당 소켓의 관련 타이머를 다시 500ms 시간 초과로 재설정하십시오.

타이머가 만료되면 (소켓이 500ms 동안 비활성 상태이기 때문에) 타이머가 epoll 개체에서 "읽기 준비"상태가되고 epoll_wait에서 대기하는 모든 스레드가 깨어납니다. 그런 다음 해당 스레드는 타이머의 연관된 소켓에 대한 시간 초과를 처리 할 수 ​​있습니다.