Computer Security

#24 I/O Multiplexing(select) 본문

리눅스 시스템 프로그래밍

#24 I/O Multiplexing(select)

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

한 application에서 여러 fd에 대해 read를 하려면?

 

1. polling with non-blocking mode

 

2. multi-thread

 

3. I/O Multiplexing

 

 

 

 

 


2. multi-thread

 

  • 하나의 프로세스를 다수의 실행 단위로 구분하여 자원을 공유하고
    자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상시키는 것
  • 하나의 프로그램에 동시에 여러개의 일을 수행할수 있도록 해주는 것이다.

 

 

 

 

 


3. I/O Multiplexing

 

 I/O Multiplexing API :select()/poll()/epoll()

 

여러개의 fd들이 있었을 때, API에 등록하고(이거에 대해 반응할 것이다!) 하나의 프로세스&쓰레드가 API를 call해서 전체 fd를 한꺼번에 감시한다.

 

만약 어떤 특정 fd에서 이벤트가 발생하면, 하나의 프로세스&쓰레드는 발생한 이벤트 fd를 인지하고 읽는다.

 

 

 

 

 

 


공통 동작 방식

 

1. Application이 내가 관심있는 fd를 Register해준다.

 

2. Application이 I/O Multiplexer를 호출해서 blocking 한다.

 

3. 어떤 fd에서 이벤트가 발생하면, I/O Multiplexing API가 리턴해준다.

 

4. 읽을 수 있는 상황이면, 어느 fd에서 이벤트가 발생했는지 읽는다. 

 

 

 

Application 입장에선 여러개의 쓰레드를 생성하지 않아도 한번에 감시가 가능하다!

 

 

 

 

 

 


select()


Multiplexing select()

 

 

지정한 소켓의 변화를 확인하고자 사용되는 함수이다.

 

소켓셋에 저장된 소켓에 변화가 생길 때 까지 기다리고 있다가  소켓이 어떤 동작을 하면 동작한 소켓을 제외한 나머지 소켓을 모두 제거하고 해당되는 소켓에 대해 진행을 한다.

 

 

 

 

 


Multiplexing select 동작 방식

 

 

1. FD_SET : 감시해야할 fd들을 모아서 설정한다.

 

2. Call select() with fds  : 셀렉트를 출력한다.

 

3. 이벤트가 발생하면 select()가 리턴해준다.

 

4. 특정 fd에 적당한 operation을 수행할 수 있다.

 

 

 

 

 

 

 


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

 

 

 

 

반환 값

- 양수 : event가 발생한 fd의 개수

 

- 0 : timeout 발생

 

- -1 : 에러 발생

 

 

 

 

 

 

 


 

struct timeval {
    long tv_sec ;   /*seconds*/
    long tv_usec ;  /*microseconds*/
};

void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);

(example)
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(0, &rfds);

이벤트가 발생한 fd인지 찾는  API : FD_ISSET - 하나씩 체크하는 방식이다.

 


예제)

 

fd_set rfds  : FD_SET변수 선언

 

FD_ZERO(&rfds) : 초기화

 

FD_SET(0, &rfds) : 0번 fd를 rfds변수에 설정한다.

 

 

반응형

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

#26 I/O Multiplexing : epoll  (0) 2022.10.01
#25 I/O Multiplexing(select) (실습)  (0) 2022.09.30
#23 파일 이벤트 (실습)  (0) 2022.09.28
#22 파일 이벤트  (0) 2022.09.27
#21 파일 속성 제어 (실습)  (2) 2022.09.26
Comments