epoll은 Linux 커널 버전 2.5.44에서 처음 도입된 확장 가능한 I/O 이벤트 알림 메커니즘을 위한 Linux 커널 시스템 호출입니다. 그 기능은 I/O가 가능한지 여부를 확인하기 위해 여러 파일 설명자를 모니터링하는 것입니다.
(위키백과)
epoll에 소켓 fd를 등록하고 소켓에 이벤트가 발생한면 바로 알림을 받아 처리를 할 수 있습니다.
성능은 select < poll < epoll
epoll 파일 디스크립터의 저장소 생성
커널 공간에 size 만큼 epoll 파일 디스크립터를 생성하는 함수.
리눅스 2.6.8부터는 인자인 size를 무시하기 때문에 0 이상의 값으로만 넣어주면 된다.
소멸시 close 함수 호출하여 종료 필요.
#incude <sys/epoll.h>
int epoll_create(int size);
@param size: epoll 인스턴스의 크기 정보
@return : 성공 : 이벤트가 발생한 파일 디스크립터의 수 / 실패 : -1
저장소에 파일 디스크립터 등록/수정/삭제
#include <sys/epoll.h>
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
@param epfd : 모니터링 대상을 등록할 epoll 인스턴스의 파일디스크립터
@param op : 모니터링 대상의 추가,삭제, 변경여부
@param fd : 등록할 모니터링 대상의 파일 디스크립터
@param event : 모니터링 대상의 관찰 이벤트 유형
EPOLL_CTL_ADD : 파일스크립터 를 epoll 인스턴스에 등록
epoll_ctl(A, EPOLL_CTL_ADD, B, C);
epoll 인스턴스 A에 C라는 특정 이벤트를 관찰할 목적으로 파일 디스크립터 B를 등록한다.
EPOLL_CTL_MOD : 등록된 파일 스크립터의 이벤트 발생 상황 변경
EPOLL_CTL_DEL : 파일스크립터 를 epoll 인스턴스에서 삭제
epoll_ctl(A, EPOLL_CTL_DEL, B, NULL);
epoll 인스턴스 A에 파일 디스크립터 B를 삭제한다.
@return : 성공 : 0 / 실패 :1
파일 디스크립터의 변경 대기
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
@param epfd : 이벤트 발생의 모니터링영역인 epoll 인스턴스의 파일 디스크립터
@param events : 이벤트가 발생한 파일디스크립터가 채워질 버퍼의 주소값
@param maxevents : 두번째 인자로 전달된 주소값의 버퍼에 등록 가능한 최대 이벤트수
@param timeout : 1/1000초 단위의 대기시간, -1 전달시 이벤트가 발생할 때까지 무한대
@return : 성공 : 이벤트가 발생한 파일 디스크립터의 수 / 실패 : -1
모니터링 대상의 이벤트 지정 이나 epoll_wait 호출시 발생한 이벤트 내용을 담을 수 있는 구조체
events에는 정의된 event 상황을 대입하고 epoll_data 공용체의 int fd를 통해 대상 소켓을 지정할 수 있음
typedef union epoll_data {
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event {
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
ex 서버의 소캣 생성후 client 의 요청을 감시할수 있도록 등록한다.
// descripter of epoll instance
epfd = epoll_create(EPOLL_SIZE);
// storage for occurring epoll event
ep_events = (epoll_event*) malloc(sizeof(struct epoll_event) * EPOLL_SIZE);
// Which Event?
struct epoll_event event;
event.events = EPOLLIN;
event.data.fd = serv_sock;
// Register file descripter [serv_sock], which kind is [event] to epoll instance [epfd]
epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);