Computer Security

#27 I/O Multiplexing : epoll (실습) 본문

리눅스 시스템 프로그래밍

#27 I/O Multiplexing : epoll (실습)

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

epoll API를 이용해서 inotify fd 와 stdin fd에 대해서 read 이벤트를 감시하고있다가 이벤트가 발생하면 해당 fd에 가서 정보를 읽어오자.

 

 

 


 

1. 이전에 작성했던 select.c 파일을 epoll.c로 카피한다. 아래는 select.c 코드이다.

 

 

 

 

 

 


2. select 부분을 삭제해주고 int epfd 선언 후 epoll_create를 이용해서 instance를 생성한 뒤, 예외처리 해준다.

epoll_create1(0)

#include <sys/epoll.h>

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

 

 

 

 

 

 


3. struct epoll_event ep_event  선언 후, epoll_ctl API를 통해서 감시를 원하는 fd를 설정 해준다.

epoll_ctl (inotify fd)

 

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 : 감시 이벤트 명시

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에서는 단 한번의 이벤트만 발생

 

 


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

 

해당 fd에 대해서 EPOLLIN 이벤트에 대해 감시하게끔 설정 해보자.

 

 

과정

1. struct epoll_event event 선언

 

2. memset 이용해 초기화

 

3. event.events 안에 EPOLLIN을 넣어준다.

 

4. event.data.fd 안에 inotify fd인 fd를 넣어준다.

 

5. epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);

 

6. 예외 처리 해준다.

 

 

 

 

 

 


4. inotify fd에 대해서 감시하는 코드를 위에 3번에서 작성 했으니, STDIN 을 감시하는 코드를 작성하자.

epoll_stl (STDIN fd)

위의 내용과 똑같이 fd 대신 STDIN_FILENO 를 넣어준다.

 

 

 

 

 

 


5. while 문안에서 epoll_wait API를 이용하자.

epoll_wait

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

 

epfd : epoll instance   - epfd

 

events : 발생한 이벤트 정보  - &event

 

maxevents : events 변수의 최대 엔트리 개수 - 1(1개씩)

 

timeout : 최대 blocking timeout(milliseconds 단위) - 5000(5초)

 

과정

1. memset 으로 초기화 해준다.

2. epoll_wait 작성

 

 

 

 

 

 


6. 예외 처리 해준다.

ret == -1  : 에러처리

 

ret == 0 : timeout

 

ret > 0 : 이벤트 발생

-FD_ISSET 을 이용해서 어느 fd에서 이벤트가 발생한 것인지 찾아준다.

-inotify 에서 이벤트가 발생을때와 STDIN_FILENO에서 발생했을 때 각각의 코드를 짜준다.

 

 

 

 

 

 


7. 전체 코드이다.

epoll.c

 

 

 

 

 


8. gcc 컴파일 후, 실행 시켜보자.

./epoll

아무것도 안하고 기다리면 5초 뒤, timeout이 뜬다.

다른 터미널을 열어서 vi epoll.c 명령어를 입력하니, 정상적으로 반응 하는 것을 알 수 있다!

 

반응형
Comments