2013-11-02 3 views
5

비 차단 소켓 (C/C++) 및 select을 사용하여 네트워크 통신 프로그램을 작성 중입니다. 프로그램이 꽤 크기 때문에 소스 코드를 업로드 할 수 없습니다. 매우 적극적인 테스트 세션에서 TCP 및 UDP를 자주 열고 닫는 테스트 코드를 사용합니다. 항상 한쪽 끝이 응답하지 않고 98 또는 99 % 이상의 CPU 사용량을 갖습니다. 그런 다음 gdb을 첨부합니다.CPU 사용량이 많은 select() 문제는 무엇입니까?

0x00007f1b71b59ac3 in __select_nocancel() at ../sysdeps/unix/syscall-template.S:82 
82 ../sysdeps/unix/syscall-template.S: No such file or directory. 
    in ../sysdeps/unix/syscall-template.S 

가 오류의 유형이 될 수있다 "BT"다음 보여줍니다?

$ uname -a 
Linux kiosk2 2.6.32-34-generiC#77-Ubuntu SMP Tue Sep 13 19:39:17 UTC 2011 x86_64 GNU/Linux 
+0

그래서 문제가 무엇입니까? – Tshepang

답변

26

이 코드를 보지 않고 말을하는 것은 불가능하지만, 선택 기반의 루프가 ~ 100 %의 CPU 사용률에서 회전 시작 종종 때 소켓 중 하나 이상이 당신이 기성 있습니다보고 select() 말했다 때문입니다 read (및/또는 write-ready)를 사용하여 블로킹 대신 즉시 select()이 반환하지만 그 코드는 해당 소켓의 모든 데이터를 실제로 recv() (또는 send())으로 무시합니다. 아무것도 읽고 쓰지 못하면 이벤트 루프는 select()을 다시 호출하여 다시 잠자기 상태로 만들려고 시도하지만 물론 소켓의 데이터 (또는 쓰기 가능 상태의 버퍼 공간)는 여전히 처리 대기 중입니다 그래서 select() 즉시 반환, 다시 버그 코드는 다시 주위 읽기를 할 (또는 write())을 무시하고 주위에 우리는 최고 속도로 이동 :

또 다른 가능성은 당신이 select()에 시간 초과 값 전달되는 것 0 또는 0에 가깝기 때문에 select()을 호출하기 전에 timeval 구조체를 다시 초기화하는 것을 잊어 버렸을 때 종종 발생하는 소켓이 준비되지 않은 경우에도 매우 빠르게 select()이 반환됩니다. select()의 일부 구현은 반환하기 전에 수정하기 때문에 매번 timeval 구조체를 다시 초기화해야합니다.

제 제안은 select() 전화를 걸기 직전과 직후에 printf (또는 좋아하는 동급)를 입력하고 오류를 재현 할 때 그 출력을 관찰하는 것입니다. 그것은 select()에 대한 단일 호출 내에서 회전이 일어나고 있는지, 또는 무엇이 select()이 즉시 반복적으로 반환되는지 여부를 보여줍니다.

+3

질문에 소스 코드가 없을 때 보았던 가장 좋은 답변 중 +1 –