카테고리 없음

[TIL] Blocking, Non-Blocking I/O

s00ng 2025. 3. 3. 08:10

Blocking I/O

I/O 작업을 요청한 프로세스/스레드는 요청이 완료될때까지 차단(Block) 됨

  1. 하나의 Thread에서 Blocking으로 동작하는 read system call을 호출한다.
  2. OS Kernel로 전환하기위해 Context-switching이 발생한다
  3. Kernel에서는 read I/O를 실행하여 외부 소켓과 connection을 맺는다. (TCP 기준)
  4. 외부 소켓으로부터 데이터를 읽어, Kernel space에서 User space(Application)로 데이터를 전달한다.
  5. OS Kernel로부터 데이터를 전달받은 Thread는 그제서야 다른 작업을 처리한다.

 

+) Socket에게 Block I/O란?

  • socket A는 네트워크상에서 Data를 읽는 주체, socket S는 Data를 쓰는 주체이다.
  • socket A에 read system call을 호출한 Thread는 recv_buffer에 데이터를 읽을 때까지 Block 된다.
  • socket S에 write system call을 호출한 Thread는 send_buffer의 여유공간이 생길때까지 Block 된다.
    • send_buffer의 저장공간이 가득 차있다면 데이터를 Buffer로 쓰는 동작 방식에서는 데이터를 쓸 수 없기 때문에 Buffer에 여유 공간이 생길때까지 Block 되는 것이다.

 

 

Non-Blocking I/O

I/O 작업을 처리하는동안 스레드가 다른 작업을 수행할 수 있다

 

 프로세스/스레드를 Block 시키지 않고 요청에 대한 현재 상태를 즉시 리턴하여 I/O 작업을 처리하는 도중에 다른 작업을 처리할 수 있도록 동작하는 방식

 

  1. 하나의 Thread에서 Non-blocking으로 동작하는 read system call을 호출
  2. OS Kernel로 전환하기위해 Context-switching이 발생한다
  3. OS Kernel에서는 아직 데이터가 준비되지 않았음을 표현하는 -1값과 EAGAIN같은 Error code를 Thread로 즉시 리턴한다.
  4. Thread는 Block 되지 않고 다른 작업을 수행한다
  5. 외부 소켓으로부터 수신한 데이터는 OS Kernel에 적재되며 데이터를 준비한다.
  6. Thread는 다시 read system call을 호출한다.
  7. 이제는 OS Kernel level에서 데이터가 준비되어있기 때문에 data를 OS Kernel에서 User space로 전달한다.

 

+) Socket에게 Non-Block I/O란?

  • Blocking I/O에서는 read system call이 호출되면 recv_buffer에서 데이터를 읽을때까지 대기, Block 되었다.
  • 하지만 Non-Blocking I/O에서는 read system call이 호출되면 recv_buffer에 데이터가 준비되었다면 바로 읽고, 데이터가 없다면 데이터가 없음을 바로 return한다. 즉, Block 되지 않는다.
  • Socket을 통해 데이터를 송신하는 입장에서도 send_buffer가 가득차있다면 send_buffer에 여유공간이 생길때까지 기다리지 않고 적절한 에러코드와 함께 return하여 Block되지 않게끔 동작한다.

 

 

I/O 작업 완료를 확인하는 방법

1. 완료되었는지 반복적으로 확인

  1. read system call을 non-blocking 으로 호출
  2. buffer에 데이터가 준비되지 않았다면 -1과 에러코드 반환
  3. 다른 작업을 수행하다 다시 read system call 호출
  4. 데이터가 준비될때까지 반복

 

문제

  • 완료된 시간과 Thread가 작업 완료를 확인한 시간 사이의 Gap이 존재하여 처리 속도가 느려질 수 있음
  • 작업이 완료되었는지 반복적으로 확인하는 작업 자체가 CPU를 낭비하는 행위

 

 

2. I/O Multiplexing (다중 입출력)

  • 관심있는 I/O 작업들을 동시에 모니터링하고 그 중에 완료된 작업들을 한 번에 알려주는 방식
  • 네트워크 통신에 많이 사용됨

  1. I/O Multiplexing system call을 호출하여 2개의 socket을 모니터링한다.
  2. OS Kernel에서는 2개의 Socket을 통해 Read I/O 작업을 수행
  3. system call을 호출한 Thread는 여러 형태가 가능 (Blocked 또는 Non-Blocked)
  4. socket에 데이터가 준비되면 OS Kernel 레벨에서 데이터가 준비되었음을 notify 해줌
  5. 데이터가 준비되었음을 알게된 Thread는 Socket으로부터 Buffer에 적재된 데이터를 읽어와서 처리