Computer Security

#25 I/O Multiplexing(select) (실습) 본문

리눅스 시스템 프로그래밍

#25 I/O Multiplexing(select) (실습)

쿠리 Kuri 2022. 9. 30. 18:30
반응형

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

 

 

 

 

 


이전에 작성했던 inotify 기능을 작성했던 코드에  stdin fd에대해 읽어오는 부분 + select로 I/O Multiplexing 하는 부분을 붙혀서 코드를 작성 해보자.

 

 

 


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

inotify.c

메인함수에서부터 inotify객체를 생성하고 watch를 2개 추가한 뒤, while 루프를 해서 read 를 직접적으로 호출하는 예제였다.

 

우리는 stdin 에대해서도 I/O multiplexing을 해야하니 코드를 수정해야한다.

 

stdin의 fd는 파일 실행시 이미 열려있는 상태이다. ( fd : STDIN_FILENO )

 

 

 

 

 

 


2. select API를 추가 해주자.

#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

 

파라미터

- nfds : fdset에 포함된 fd 중 가장 큰 값 +1

 

- readfds : read가 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능

 

- writefds : write가 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능

 

- exceptfds : exception이 가능한 시점을 감시하기 위한 fd set, NULL 입력 가능

 

- timeout :

     - non NULL : 최대 block timeout 값 지정

     - NULL : 무한 blocking

 

 

 

우리는 inotify fd 와 STDIN_FILENO fd를 두개를 처리해야한다.

 

while문 안에있는 read 대신 select API를 호출해주자.

 

 


과정

 

 


i) nfds :  fd > STDIN_FILENO ? fd +1 : STDIN_FILENO +1 

           (inotify fd 와 STDIN_FILENO fd 둘중 가장 큰값을 찾아내서 +1 해줘야 한다.)

 

 

 

ii)readfds 

 

1. fd_set 변수를 선언한 뒤, FD_ZERO를 이용해서 초기화하고, FD_SET으로 설정 해주자.

2. fd를 fds에 설정한다.

3. STDIN_FILENO를 fds에 설정한다.

4. readfds 에 &fds 를 넣어준다. 

 

 

 

iii) writefds :  NULL 

 

 

 

iv) exceptfds : NULL 

 

 

 

 

v) timeout :  struct timeval timeout 변수를 선언하고 설정해준다.

 

 

 

 

Vi) return value의 반환 값을 참고해 예외처리를 해준다.

예외처리

ret == -1  : 에러처리

 

ret == 0 : timeout

 

ret > 0 : 이벤트 발생

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

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

 

 

 

 

 

Vi) 최종 완성된 select  부분 코드이다.

select

전체적인 흐름 

 

1. fds 초기화 

 

2. inotify , STDIN_FILENO 설정

 

3. timeout 5초설정

 

4. select 함수 설정

 

5. 예외처리를 하면서 FD_ISSET을 이용해서 i) inotify에서 이벤트일 경우 ii) STDIN 이벤트일경우  두가지에 대해 코드를 작성 해준다.

 

 

 

 

 

 


3. 완성된 전체 코드이다.

 

 

 

 

 

 

 


4. gcc 컴파일을 해준다.

gcc

 

 

 

 

 


5. ./select 를 이용해 실행 시켜보자.

 

./select

기다리니 5초에 한번씩 timeout이 발생한다.

 

 

 

 

 

 

vi select

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

반응형

'리눅스 시스템 프로그래밍' 카테고리의 다른 글

#27 I/O Multiplexing : epoll (실습)  (0) 2022.10.02
#26 I/O Multiplexing : epoll  (0) 2022.10.01
#24 I/O Multiplexing(select)  (0) 2022.09.29
#23 파일 이벤트 (실습)  (0) 2022.09.28
#22 파일 이벤트  (0) 2022.09.27
Comments