2014. 1. 20. 21:28ㆍPrograming/C Language
epoll은 poll의 일종이며 edge trigger 인터페이스 또는 level trigger 인터페이스로서 사용하는 것이 가능하고 감시하는 파일 디스크립터의 수가 많은 경우에도 사용할 수 있다. epoll 세트를 설정하거나 제어하거나 하기 위해서 다음의 3개의 시스템 콜이 제공되고 있다.
epoll 세트는 epoll_create 으로 작성되는 파일 디스크립터에 접속된다. 그리고 특정의 파일 디스크립터에 대한 관심 (역주: 어떤 이벤트를 감시할까 등)을 epoll_ctl 로 등록한다.
마지막에 epoll_wait 로 실제의 이벤트 대기를 개시한다.
EPOLL의 핵심 API 함수
int epoll_create(int size); epoll_create()는 이벤트를 저장하기 위한 size만 큼의 공간을 커널에 요청한다. 커널에 요청한다고 해서 반드시 size만큼의 공간이 확보되는 건 아니지만 커널이 대략 어느 정도의 공간을 만들어야 할지는 정해줄 수 있다. 수행된 후 파일 지정자를 되돌려 주는데, 이 후 모든 관련작업은 리턴된 파일 지정자를 통해서 이루어지게 된다. 모든 작업이 끝났다면 close()를 호출해서 닫아주어야 한다. int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); 실제 이벤트가 발생하는걸 기다리고 있다가, 이벤트가 발생하면 이벤트 관련 정보를 넘겨주는 일을 한다. epfd는 epoll_create(2)를 이용해서 생성된 epoll지정자이다. 만약 이벤트가 발생하면 리턴하게 되는데, 리턴된 이벤트에 관한 정보는 events에 저장된다. maxevents는 epoll이벤트 풀의 크기다. timeout는 기다리는 시간이다. 0보다 작다면 이벤트가 발생할 때까지 기다리고, 0이면 바로 리턴, 0보다 크면 timeout 밀리세컨드 만큼 기다린다. 만약 timeout시간에 이벤트가 발생하지 않는다면 0을 리턴한다. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); 이벤트풀을 제어하기 위해서 사용한다. poll(2)와 매우 비슷하게 작동한다. op는 fd에 대해서 어떤 작업을 할것인지를 정의하기 위해서 사용된다. op가 실행된 결과는 event구조체에 적용된다. 다음은 epoll_event구조체의 모습이다. typedef union epoll_data {
|
동작 순서
1. 파이프의 읽기 측을 나타내는 파일 디스크립터 (RFD) 가 epoll 디바이스의 내부에 추가된다. 2. 파이프에 쓰기를 하는 프로그램이 2Kb 의 데이터를 파이프의 쓰기측에 기입한다. 3. epoll_wait 를 호출하면 읽기 가능(ready)인 파일 디스크립터로써 RFD가 돌아간다. 4. 파이프로부터 읽어내는 프로그램이 1Kb 의 데이터를 RFD로부터 읽어낸다. 5. epoll_wait의 호출을 한다. RFD 파일 디스크립터가 EPOLLET 플래그를 사용해 epoll 추가되고 있으면 이용 가능한 데이터가 파일 입력 버퍼에 아직 존재해 리모트의 접속처(peer)가 이미 보내진 데이터에 근거해 응답을 기대하고 있기 때문에 스텝 5의 epoll_wait 의 호출로 행할 가능성이 있다. 이것은 edge trigger 이벤트 배송에서는 모니터 하고 있는 파일로 이벤트가 떠났을 때에만 이벤트가 배송되기 때문에 있다. 상기의 예에서는 2로 행해진 쓰기에 의해 RFD 에 관한 이벤트가 생성되어 3로 이벤트가 소비(consume) 된다. 4 로 행해지는 읽기 조작에서는 전부의 버퍼 데이터를 소비하지 않기 때문에 스텝 5 에서 행해지는 epoll_wait 의 호출이 무기한으로 잠글지도 모른다. EPOLLET 플래그 (edge trigger)와 함께 사용하는 경우 epoll 인터페이스는 블록 하지 않는 파일 디스크립터를 사용해야 하는 것이다. 이것은 블록 되는 읽기나 기입에 의해 , 복수의 파일 디스크립터를 취급하는 태스크를 굶주림(starve) 시키지 않게 하기 위한 것이다. epoll 를 edge trigger (EPOLLET) 인터페이스로서 사용하기 위해서 제안되는 방법은 이하와 같고 흔히 있는 함정을 피하는 방법도 계속해 말한다. 반대로 level trigger 인터페이스로서 사용하는 경우는 epoll 은 정말로 보다 고속의 poll이며 사용법이 같아서 poll이 사용되고 있는 곳은 어디에서라도 사용할 수가 있다. edge trigger를 사용했을 경우에서도 복수의 데이터를 수신하면 복수의 epoll 이벤트가 생성되므로 호출 측에는EPOLLONESHOT 플래그를 지정하는 옵션이 있다. 이 플래그는 epoll에 대해서 epoll_wait 에 의한 이벤트를 수신한 다음에 관련하는 파일 디스크립터를 무효로 시킨다. EPOLLONESHOT 플래그가 지정되었을 경우 epoll_ctl 에 EPOLL_CTL_MOD 를 지정해 파일 디스크립터를 재차 사용할 수 있도록 하는 것은 호출 측의 책임이다. |
EPOLL을 이용한 간단한 ECHO(채팅Chatting) 서버 사용되는 전역 변수
사용할 접속자 구조 초기화
EPOLL 생성 및 초기화
서버가 이벤트를 기다리는 로직
누군가 접속했을때 처리하는 로직 (ACCEPT)
누군가 WRITE를 요청했을시의 READ해서 받는 처리
접속자에게 SEND 전송하는 로직 처리
|
'Programing > C Language' 카테고리의 다른 글
MOD(%) 연산의 AND(&) 연산으로의 처리 (0) | 2014.01.20 |
---|---|
#ifdef(if defined)와 #if defined (0) | 2014.01.20 |
ERROR : invalid storage class for function (1) | 2014.01.20 |
ERROR : expected declaration or statement at end of input (0) | 2014.01.20 |
Warning : undefined; assuming extern returning int (0) | 2014.01.20 |