select()소켓모델 네트워크 프로그램개발에 있어서 한계를 극복하는 방법은 ?
글쓴이: ljh0431 / 작성시간: 화, 2010/02/02 - 5:46오전
select()소켓모델은 UNIX에서 많이 사용한다고 하더군요.
이 select()로는 64개 이하만 사용할 수 있다고 나와 있네요.
64개 이상처리하는 서버를 만들려면 어떤 식으로 로직을 짜야 하나요 ?
select()가 blocking상태로 들어가면 select() 다음 행으로 명령어가 넘어가도록 할 수가 없어서,
새로운 소켓이 발생되면 어떻게 소켓추가사실을 알려야 하나요 ?
어떤 방식으로 프로그램을 개발해야 할지 잘 안떠오르네요.
궁금합니다.
Forums:
poll()을 사용합니다.
poll()을 사용합니다.
epoll()이 있습니다.
찾아보세요^^
...
제가 알기로는 대부분의 시스템에서 64개는 가뿐히 넘고 수백 개씩 사용할 수 있습니다. 예전 회사에 근무할 때 어느 시스템에서 1024개 제한이 있어서 그걸 풀려면 커널 설정을 변경해야 한다고 어지어찌 설정을 바꾸고 그런 일이 있었던 기억이 나네요.
다만 select라는 함수가 구조적으로 fd 갯수가 많아질수록 성능이 급격히 나빠진다고 합니다. 그러므로 수백 개가 가능하다는 건 그냥 가능하다는 얘기일 뿐이지, 성능이 중요하다면 다른 방법을 고려하시는 게 좋겠습니다.
FD_SETSIZE로
FD_SETSIZE로 결정되는데, glibc에선 1024입니다. 이 값이 POSIX 최소값인지 glibc에서 그냥 쓰는 값인진 모르겠습니다. 리눅스에서 이 값은 fd_set 크기 결정하는데만 쓰이고, libc에선 안 까보고 그냥 커널로 올라가는데, 커널 구현은 크기 제한이 있는 게 아니어서 그냥 FD_SETSIZE를 undef하고 다시 높은 값으로 올려서 컴파일하면 더 크게 쓸 수 있습니다.
select/poll 모두 fd 수가 증가함에 따라 오버헤드가 증가합니다. 인터페이스의 구조적인 문제인데, 이벤트가 발생해서 유저스페이스로 돌아갈때마다 전체 컨택스트가 없어지기때문에 다음 이벤트를 보려면 전체를 한 번 더 훓어야합니다. 그래서 최악의 경우엔 fd 수를 N 이벤트 수를 E 라고 하면 복잡도가 O(N*E)이 됩니다. 로드가 증가함에 따라 한번 돌 때마다 읽어올 수 있는 이벤트 수가 늘어서 보통은 그것보단 좋게 나오긴 하지만요. 그래도 몇백개 정도까진 문제가 되진 않습니다. 시피유도 빠르니 10k이하에선 어지간한 경우엔 큰 문제는 없을겁니다.
이거 고치려고 freebsd엔 kqueue가 linux엔 epoll이 있고, libevent처럼 크로스플랫폼 라이브러리들도 꽤 있습니다.
근데 뭐 만드시려는지 모르겠지만 이벤트 인터페이스위에 스테이트 머신으로 만드는 거 처음엔 괜찮아보여도 나중에 복잡해지면 관리 불가상태로 쉽게 빠지고, 지금에와선 복잡만하고 멀티쓰레드로 만드는 것에 비해 성능상의 이점이 사실상 없습니다. 유일하게 차이가 느껴질만한 부분은 스택으로 인한 메모리 사용량 증가정도인데, dynamic link 피하고 스택 사용량 적당히 신경쓰면서 만들면 꽤 줄여서 사용할 수 있구요. 아이들 세션이 아주 많은 경우가 문제가 되는데 아이들 세션들만 event 인터페이스로 보다가 활성화되면 쓰레드로 넘겨주는 식으로 만들면 되구요.
linux 에서 epoll 이
linux 에서 epoll 이 들어오기 전에 rtsig 도 많이 이용했었습니다.
rtsig은 코너케이스
rtsig은 코너케이스 핸들링이 후덜덜이라;;;
댓글 달기