select timeout 관련
글쓴이: asleea / 작성시간: 일, 2013/02/03 - 11:59오전
아래 code는 20ms timeout을 갖는 select함수를 1000번 수행하고 걸린 시간을 1000으로 나누어 평균적인 시간을 계산한 code입니다.
모니터 해야하는 fd를 STDIN_FILENO으로하여 항상 select가 항상 timeout으로 리턴하도록 하였습니다.
처음 생각에는 제가 설정한 20ms보다 더 길게 나올것으로 예상하고 얼마나 더 많이 나올까 하고 코딩을 하였는데 실제 값은
((CPU가 select를 하는 프로세스만 잡고 있는 것이 아니라 다른 일도 해야 하기때문에 select에서 블록되어있을때 다른일을 시작
하였다면 timeout이 되어도 하던일을 다 끝내고 select를 리턴하지 않을까 하는 생각에 그렇게 생각함))
timeout으로 설정한 값보다 더 작은 값이 나오더군요 (12~17, 18 ms 정도)
왜 그럴까요?
loop를 없애고 timeout을 3초정도로 설정하였도 역시 3보다 적은 2.xxxx초가 나오는더군요
#include<stdio.h> #include<unistd.h> #include<sys/time.h> #include<sys/select.h> #include<sys/time.h> int main() { int i = 0; struct timeval timer, Start, End; long time; timer.tv_sec = 0; timer.tv_usec = 20; fd_set readset; gettimeofday(&Start, NULL); while(i < 1000){ FD_ZERO(&readset); FD_SET(STDIN_FILENO, &readset); int rtv = select(STDIN_FILENO + 1, &readset, NULL, NULL, &timer); if(rtv != 0){ fprintf(stderr ,"error!\n"); return 1; } fprintf(stderr, "%d\n", i); i++; } gettimeofday(&End, NULL); Start.tv_sec = (End.tv_sec - Start.tv_sec)*1000000L; Start.tv_usec = End.tv_usec - Start.tv_usec; if(Start.tv_usec < 0){ Start.tv_sec -= 1L; Start.tv_usec += 1000000L; } time = Start.tv_sec*1000000L + Start.tv_usec; time = time/1000L; fprintf(stderr, "%ld usec\n", time); return 0; }
Forums:
음 ..
20 us 이면 엄청 작은 시간이네요. 20 ms 를 생각하셨다면 tv_usec 에 20000 을 넣으셔야 합니다.
그리고 linux select 는 return 하면서 timeout 에 남은 시간을 설정합니다.
그래서 매번 select 들어갈 때 timeout 을 다시 설정 해줘야 합니다.
(위 코드에서는 두번째 loop 부터 timer 의 값이 모두 0 으로 되어 있을 겁니다.)
그리고 tv_sec 에 1000000L 을 두번 곱하셨는데.. 첫번째 꺼는 잘못 쓰신것 같네요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
댓글 달기