Computer Security

#26 I/O Multiplexing : epoll 본문

리눅스 시스템 프로그래밍

#26 I/O Multiplexing : epoll

쿠리 Kuri 2022. 10. 1. 18:30
반응형

epoll

 

리눅스에서 select의 단점을 보완하여 사용할 수 있도록 만든 I/O통지 모델이다.

 

파일 디스크립터를 사용자가 아닌 커널이 관리를 하며, 그만큼 CPU는 계속해서 파일 디스크립터의 상태 변화를 감시할 필요가 없다.

 

select처럼 어느 파일 디스크립터에 이벤트가 발생하였는지 찾기 위해 전체 파일디스크립터에 대해서 순차검색을 위한 FD_ISSET 루프를 돌려야 하지만, Epoll의 경우 이벤트가 발생한 파일 디스크립터들만 구조체 배열을 통해 넘겨주므로 메모리 카피에 대한 비용이 줄어든다.

 

 

 

 

 

 


epoll 과정

 

 

1. epoll instance 를 생성한다

 

2. epoll_ctl(ADD) API를 통해서 감시할 fd들을 ADD해준다.

 

3. epoll_wait()라는 API를 통해서 이벤트를 기다린다.

 

4. 이벤트가 발생하면 리턴한다.

 

5. application이 정보를 해석해서 적절한 처리를한다.

 

 

 

 

 

 


epoll instance 생성 API 

int epoll_create(int size);
int epoll_create1(int flags);

파라미터

- size : 무시되지만 반드시 양수여야 한다.

 

- flags 

    - EPOLL_CLOEXEC : close-on-exec

 

 

 

반환 값

- 성공 시 epoll instance(non-negative)

- 실패 시 -1

 

 

 

 

 


epoll 제어 API

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

파라미터

- epfd : epoll instance

 

- op : 수행할 동작

     - EPOLL_CTL_ADD : 추가

     - EPOLL_CTL_MOD : 변경 
     - EPOLL_CTL_DEL : 삭제


- fd : 감시할 fd

 

- event : 감시 이벤트 명시

 

 

 

반환 값

- 성공 시 0

- 실패 시 -1

 

 

 

 

 

 


epoll 감시 API

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

파라미터

- epfd : epoll instance

 

- events : 발생한 이벤트 정보

 

- maxevents : events 변수의 최대 엔트리 개수

 

- timeout : 최대 blocking timeout(milliseconds 단위)

 

 

반환 값

- 성공 시 0

- 실패 시 -1

 

 

 

 

 


epoll event struct

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 */
};

 

 

 

 

 


Event mask

epoll event mask epoll_ctl epoll_wait Description
EPOLLIN O O read 가능
EPOLLOUT O O write 가능
EPOLLRDHUP O O 연결 종료, 상대방 소켓 셧다운
EPOLLPRI O O TCP socket에서 OOB 데이터 수신 등 예외 상황
EPOLLERR X O 에러가 발생한 상황
EPOLLHUP X O 장애가 발생한 상황
EPOLLET O X 이벤트 감지를 엣지 트리거(Edge trigger)로 설정
EPOLLONESHOT O X 해당 fd에서는 단 한번의 이벤트만 발생
 

 

 

 

 

 


Edge Trigger(ET) (Epoll)

 

특정 상태가 변화하는 시점에서만 감지.

 

특정 디지털 신호 000 111 000 111 000 111 일 경우 신호가 0에서 1로 변하는 시점에서만 이벤트가 발생한다.

 

한번에 읽을 수 있는 바이트 이상의 데이터가 오게 된다면 추가적인 작업을 따로 해주어야 한다.

 

ET로 작동하게 하려면 Non-blocking 소켓으로 생성해 줘야 하며 epoll에 관심 FD로 등록 할 때 EPOLLET로 설정해 주어야 한다.

 

 

 

 

 

 


Level Trigger(LT) (select API)

 

특정 상태가 유지되는 동안 감지.

 

특정 디지털 신호 000 111 000 111 000 111 에서 1에 대한 Trigger 라면 1이 유지되는 시간동안 횟수에 상관없이 이벤트가 발생한다.

 

소켓 버퍼가 비어지는(0이 되는) 순간까지 계속해서 이벤트가 발생이 된다.

 

LT는 기본으로 설정되어 있으며 select나 poll은 LT만 지원이 된다.

 

 

 

 

 


select() vs epoll


select() epoll
이벤트 발생 fd 탐색 모든 fd에 대해 발생 여부 체크 이벤트 발생한 fd를 직접 알려준다.
감시 대상 fd 설정 select() 호출 시마다 설정 해야한다. 재설정 필요가 없다.
이식성 좋다 (대부분의 OS에서 지원) Linux only
성능 나쁘다 좋다
 
반응형
Comments