블록 I/O
I/O 작업을 요청한 프로세스나 스레드가 작업이 완료될 때까지 대기하는 방식이다. 이 방식은 단순하고 직관적이지만, 블록 상태로 인해 자원 활용에 비효율적일 수 있다.
물론, 스레드가 I/O 작업 때문에 블록 되는 동안, CPU 코어는 다른 스레드에게 할당될 수 있다. 이 경우 CPU는 여전히 다른 작업을 수행할 수 있지만 대량의 스레드가 블록 상태로 대기하면 시스템 자원(메모리, 스레드 관리 오버헤드 등)을 낭비할 수 있다.
동작 과정
- 스레드가
read
시스템콜을 수행한다. - 스레드는 블락 상태가 되어 커널 모드로 전환된다.
- 커널이 I/O 작업을 수행하고 관련 디바이스에 요청을 보낸다.
- 디바이스가 요청을 처리하고 커널로 응답을 보낸다.
- 커널이 유저 스페이스로 데이터를 이동시킨다.
- 스레드는 작업이 완료되면 다시 실행된다.
Socket에서의 블록 I/O
SocketS가 SocketA로 데이터를 전송하는 예를 든다.
- SocketA가
read
시스템콜을 호출한다. - SocketA는
receive
버퍼에 데이터가 들어올 때까지 블락된다. - SocketS가
write
시스템콜을 호출한다. - SocketS는
send
버퍼에 공간이 생길 때까지 블락된다.
논블록 I/O
논블록 I/O는 I/O 요청을 보낸 프로세스나 스레드가 대기하지 않고 즉시 상태를 반환받는 방식이다.
프로세스나 스레드가 블락되지 않으므로 자원을 효율적으로 활용할 수 있다.
동작 과정
- 스레드가
read
시스템콜을 수행한다. - 스레드는 커널 모드로 전환된다.
- 커널이 I/O 작업을 수행하고 관련 디바이스에 요청을 보낸다.
- 커널이 스레드에 즉시 -1과
EAGAIN
또는EWOULDBLOCK
이라는 에러 코드를 응답한다. - 스레드는 대기하지 않고 이어서 다른 작업을 실행한다.
- 디바이스가 I/O 작업을 처리하고 커널로 응답을 보낸다.
- 스레드는 I/O 작업의 결과를 확인하기 위해 다시
read
시스템콜을 수행한다. - 커널이 유저 스페이스로 데이터를 이동시킨 후, 스레드는 작업이 완료되면 다시 실행된다.
Socket에서의 논블록 I/O
- SocketA가
read
시스템콜을 호출한다.- receive 버퍼가 비어있으면 시스템콜은 바로 종료된다.
receive
버퍼에 데이터가 들어올 때까지 블락되지 않고 즉시 상태를 반환받는다.
- SocketS가
write
시스템콜을 호출한다.- send 버퍼에 공간이 다 찼다면 시스템콜은 바로 종료된다.
send
버퍼에 공간이 생길 때까지 블락되지 않고 즉시 상태를 반환받는다.
논블록 I/O 결과 처리 방식
Polling (완료됐는지 반복적으로 확인)
논블록 I/O에서 작업이 완료되었는지 반복적으로 확인하는 방식이다. 이 방법은 주기적으로 시스템 호출을 통해 I/O 작업의 완료 상태를 체크한다. 스레드가 I/O 작업의 완료를 기다리는 동안 계속 상태를 체크하는 데만 CPU 자원을 소모한다.
I/O Multiplexing (다중 입출력)
여러 I/O 작업을 동시에 모니터링하고, 이들 중 완료된 I/O 작업을 효율적으로 처리하는 방식이다. 시스템 콜은 기다리고 있는 I/O 작업이 완료되었을 때만 호출된다.
- 종류:
- select: 가장 오래된 I/O 멀티플렉싱 기법으로, 여러 파일 디스크립터를 모니터링하고, 준비된 파일 디스크립터를 반환한다. 파일 디스크립터의 수가 많아질수록 성능이 저하되며,
select
호출 시마다 모든 파일 디스크립터를 검사해야 한다. - poll:
select
와 유사하지만, 파일 디스크립터의 수에 제한이 없고,pollfd
구조체를 사용하여 효율적으로 모니터링할 수 있다. 파일 디스크립터가 많아지면 성능 저하가 발생할 수 있으며, 여전히 모든 디스크립터를 검사해야 한다. - epoll: Linux에서 제공하는 고성능 I/O 멀티플렉싱 기법으로,
select
와poll
의 성능 한계를 극복하기 위해 설계되었다. 파일 디스크립터의 상태 변화만을 처리할 수 있다. 대규모 파일 디스크립터를 효율적으로 처리할 수 있으며, 성능이 우수하다. - kqueue: BSD 계열 운영 체제에서 제공하는 I/O 멀티플렉싱 기법으로, 파일 디스크립터의 상태 변화를 감지하는 이벤트 기반 시스템이다. 높은 성능을 제공하며, 다양한 이벤트를 모니터링할 수 있다.
- IOCP (I/O Completion Ports): Windows에서 제공하는 I/O 멀티플렉싱 기법으로, 비동기 I/O 작업의 완료를 효율적으로 처리할 수 있다. 높은 성능을 제공하며, 많은 동시 I/O 작업을 효율적으로 처리할 수 있다.
- select: 가장 오래된 I/O 멀티플렉싱 기법으로, 여러 파일 디스크립터를 모니터링하고, 준비된 파일 디스크립터를 반환한다. 파일 디스크립터의 수가 많아질수록 성능이 저하되며,
Callback / Signal
Callback과 Signal은 비동기 I/O 작업을 처리하는 방식으로, I/O 작업의 완료를 비동기적으로 알리고 이를 처리할 수 있게 해 준다. 이 방법들은 특정 이벤트가 발생했을 때 자동으로 호출되는 함수나 신호를 통해 작업의 결과를 처리한다.
- 종류
- POSIX AIO (Asynchronous I/O): POSIX AIO는 POSIX 표준에 따라 비동기 I/O 작업을 지원하는 API이다. I/O 작업의 완료를 비동기적으로 처리하기 위해 aio_read, aio_write 등의 함수와 함께 완료를 알리는 신호를 사용할 수 있다.
- Linux AIO (Asynchronous I/O): Linux AIO는 Linux 커널에서 제공하는 비동기 I/O API로, I/O 작업의 완료를 비동기적으로 처리할 수 있도록 해준다.
io_submit
,io_getevents
,io_cancel
등의 시스템 콜을 사용하여 비동기 I/O를 관리한다.
728x90
'CS' 카테고리의 다른 글
[Linux] 호스트네임 관리와 네트워크 설정 (0) | 2024.08.26 |
---|---|
[Linux] 스왑 공간 (0) | 2024.08.26 |
[CS] 스레드의 종류 (0) | 2024.08.12 |
[CS] 운영 체제의 모드와 시스템 콜 (1) | 2024.08.11 |
[CS] CPU Scheduler & Dispatcher (1) | 2024.08.11 |