epoll(Linux)과 kqueue(BSD/macOS)는 수천~수만 개의 파일 디스크립터를 효율적으로 모니터링하는 I/O 이벤트 통지 메커니즘이다. 전통적인 select/poll의 O(n) 문제를 해결해 O(1) 또는 O(이벤트 수)로 처리한다.
select/poll의 문제점
select/poll:
- 매 호출마다 전체 FD 집합을 커널에 복사 O(n)
- 준비된 FD 찾으려면 전체 순회 필요 O(n)
- FD 수 제한 (select: 1024)
epoll:
- FD를 커널의 관심 목록에 등록 (한 번만)
- 준비된 FD만 반환 O(이벤트 수)
- FD 수 제한 없음
사용 방법
c
# include <sys/epoll.h>
// epoll 인스턴스 생성
int epfd = epoll_create1(0);
// FD 등록
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET; // 읽기 가능, Edge Trigger
ev.data.fd = sockfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
// 이벤트 대기
struct epoll_event events[MAX_EVENTS];
int nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout_ms);
for (int i = 0; i < nfds; i++) {
handle_event(events[i].data.fd);
}
Level Trigger vs Edge Trigger
Level Trigger (LT): 데이터가 있는 한 계속 이벤트 통지
Edge Trigger (ET): 상태 변화 시점에만 한 번 통지 (고성능)
활용
- •Nginx, Node.js, Redis의 이벤트 루프 구현
- •고성능 네트워크 서버
관련 개념