일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- Leviathan
- 커널
- radare2
- 리눅스 커널
- 알고리즘
- Pwnable.kr
- 취약점
- 시스템해킹
- wargame
- 컴퓨터구조
- 리눅스
- 드론
- 어셈블리어
- C++
- 시그널
- px4
- css
- 워게임
- Bandit
- 시스템프로그래밍
- kernel
- 프로그래밍
- pwncollege
- 리버싱
- pwn.college
- write up
- 리눅스커널
- C언어
- 시스템
- 시스템 프로그래밍
- Today
- Total
Computer Security
#24 I/O Multiplexing(select) 본문
한 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 |