본문 바로가기

linux/프로그래밍 일반

epoll 함수와 구조체 파라미터

출처 : http://blog.naver.com/PostView.nhn?blogId=ods81&logNo=50148115013

 

1. select 와 비교한 epoll의 장점
  • 상태변화의 확인을 위한, 전체 파일 디스크립터를 대상으로 하는 반복문이 필요없다.
  • select 함수에 대응하는 epoll_wait 함수 호출시, 관찰대상의 정보를 매번 전달할 필요가 없다.
상태변화 관찰에 더 나은 방법을 제공한다. 그리고 커널에서 상태정보를 유지하기 때문에 관찰대상의 정보를 매번 전달하지 않아도 된다.

2. epoll의 구현에 필요한 함수와 구조체 
  • epoll_create : epoll 파일 디스크립터 저장소 생성
  • epoll_ctl : 저장소에 파일 디스크립터 등록 및 삭제
  • epoll_wait : select 함수와 마찬가지로 파일 디스크립터 변화를 대기
3. epoll_create

 #include <sys/epoll.h>

 int epoll_creaate(int size);

 ☞ 성공 시 epoll 파일 디스크립터, 실패시 -1 반환


운영체제가 관리하는, epoll 인스턴스라 불리는 파일 디스크립터의 저장소를 생성.

소멸시 close 함수 호출을 통한 종료의 과정이 필요.


위의 함수 호출을 통해서 생성된 epoll 인스턴스에 관찰대상을 저장 및 삭제하는 함수가 epoll_ctl이고, epoll 인스턴스에 등록된 파일 디스크립터를 대상으로 이벤트의 발생 유무를 확인하는 함수가 epoll_wait이다.


⇒ epoll_create : 파일 디스크립터의 저장을 위한 저장소의 생성을 운영체제에게 요청. 즉, 운영체제에 의해서 파일 디스크립터 저장소가 생성된다.

⇒ 반환되는 파일디스크립터를 통해서 epoll 인스턴스(운영체제에 생성된 파일 디스크립터 저장소)에게 또 다른 명령을 해 줄 수도 있다.

⇒ 소멸시 close 함수 호출해 주어야 한다.


4. epoll_ctl

 

 #include <sys/epoll.h>

 int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

 ☞ 성공 시 0, 실패 시 -1 반환

 

  • epfd: 관찰 대상을 등록할 epoll 인스턴스의 파일디스크립터
  • op : 관찰 대상의 추가, 삭제 또는 변경여부 지정
  • fd : 등록할 관찰대상의 파일 디스크립터
  • event : 관찰 대상의 관찰 이벤트 유형

두번째 전달인자에 따라 등록, 삭제 및 변경이 이뤄진다.
  • EPOLL_CTL_ADD : 파일 디스크립터를 epoll 인스턴스에 등록
  • EPOLL_CTL_DEL : 파일 디스크립터를 epoll 인스턴스에서 삭제
  • EPOLL_CTL_MOD : 등록된 파일 디스크립터의 이벤트 발생상황을 변경

5. epoll_ctl 함수 기반의 디스크립터 등록
epoll_event 구조체는 이벤트의 유형 등록에 사용된다.
그리고 이벤트 발생시 발생된 이벤트이 정보로도 사용된다.

struct epoll_event event;

...

event.events = EPOLLIN;

event.data.fd = sockfd;

epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &event);

...

⇒ sockfd로 수신할 데이터가 존재하는 상황이면 이벤트가 발생된다.

⇒ epoll_ctl 함수는 event 구조체에 반환을 하게 해준다.

⇒ 반환된 event 구조체에는 이벤트가 발생된 파일 디스크립터가 들어가 있다.

 

  • EPOLLIN : 수신할 데이터가 존재하는 상황    (EPOLL_CTL의 입력, WAIT 의 출력에 모두 사용됨)
  • EPOLLOUT : 출력버퍼가 비워져서 당장 데이터를 전송할 수 있는 상황    (EPOLL_CTL의 입력, WAIT 의 출력에 모두 사용됨)
  • EPOLLPRI : OOB 데이터가 수신된 상황    (EPOLL_CTL의 입력, WAIT 의 출력에 모두 사용됨)
  • EPOLLRDHUP : 연결이 종료되거나 Half-close 가 진행된 상황, 이는 엣지 트리거 방식에서 유용하게 사용될 수 있다. 상대편 소켓 셧다운   (EPOLL_CTL의 입력, WAIT 의 출력에 모두 사용됨)
  • EPOLLERR : 에러가 발생한 상황     (EPOLL_WAIT의 출력으로만 사용됨)
  • EPOLLHUP : 장애발생 (hangup)    (EPOLL_WAIT의 출력으로만 사용됨)
  • EPOLLET : 이벤트의 감지를 엣지 트리거 방식으로 동작     (EPOLL_CTL의 입력에만 사용됨)
  • EPOLLONESHOT : 이벤트가 한번 감지되면, 해당 파일 디스크립터에서는 더 이상 이벤트를 발생시키지 않는다. 따라서 epoll_ctl 함수의 두번째 인자로 EPOLL_CTL_MOD을 전달해서 이벤트를 재설정해야 한다.    (EPOLL_CTL의 입력에만 사용됨)

6. epoll_wait

 #include <sys/epoll.h>

 int epoll_wait(int epfd, struct epoll_event *event, int maxevents, int timeout);

 ☞ 성공 시 이벤트가 발생한 파일 디스크립터의 수, 실패시 -1 반환

 

  • epfd : 이벤트 발생의 관찰영역인 epoll 인스턴스의 파일 디스크립터
  • events : 이벤트가 발생한 파일디스크립터가 채워질 버퍼의 주소값
  • maxevents : 두번째 인자로 전달된 주소값의 버퍼에 등록 가능한 최대 이벤트수
  • timeout : 1/1000초 단위의 대기시간, -1 전달시 이벤트가 발생할 때까지 무한대기

 

int event_cnt;

struct epoll_event *ep_events

...

ep_events = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);

...

event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);