출처 : http://blog.naver.com/PostView.nhn?blogId=ods81&logNo=50148115013
1. select 와 비교한 epoll의 장점
- 상태변화의 확인을 위한, 전체 파일 디스크립터를 대상으로 하는 반복문이 필요없다.
- select 함수에 대응하는 epoll_wait 함수 호출시, 관찰대상의 정보를 매번 전달할 필요가 없다.
- epoll_create : epoll 파일 디스크립터 저장소 생성
- epoll_ctl : 저장소에 파일 디스크립터 등록 및 삭제
- epoll_wait : select 함수와 마찬가지로 파일 디스크립터 변화를 대기
#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 : 등록된 파일 디스크립터의 이벤트 발생상황을 변경
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의 입력에만 사용됨)
#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); |