• Blocking I/O Model이란
    • cpu의 기본적인 I/O 모델로 리눅스에서 모든 소켓 통신은 기본 blocking으로 동작한다.
    • I/O 작업이 진행되는 동안 유저 프로세스는 자신의 작업을 중단한 채 대기하는 방식이다.

Blocking I/O

1. 유저는 커널에게 read 작업 요청
2. 데이터가 입력될 때까지 대기
3. 데이터가 입력되면 유저에게 커널이 결과를 전달한다.
  • ex. (카카오톡이 사용자가 메시지를 전송할 때까지 대기하고 있는 거라고 생각하면 이해가 쉬울 것 같다.)

 

  • Non-Blocking Model 이란
    • I/O 작업이 진행되는 동안 유저 프로세스의 작업을 중단시키지 않는 방식이다.

NonBlocking I/O

1. 유저가 커널에게 read 작업 요청
2. 데이터가 입력됐든 안됬는 요청하는 그 순간, 바로 결과가 반환된다. (데이터가 없다면 없다는 결과 메시지 EWOULDBLOCK) 반환
3. 입력 데이터가 있다면 1-2번 반복. (2번에서 결과 메시지를 받은 유저는 다른 작업을 진행한다.)
4. 입력 데이터가 있다면 커널이 유저에게 결과 전달한다.
  • 이 경우 I/O의 진행시간과 관계없이 애플리케이션에서 작업을 오랜 시간 중지하지 않고 I/O 작업을 진행할 수 있다.

  • 하지만 반복적으로 시스템 호출이 발생하기에 이역시 자원 낭비가 된다. ( 폴링 통신 방식과 비슷 ) 데이터를 입력할 때만 전송하는 게 아니라 주기적으로 계속 반복한다.

  • "너 보낸 메시지 있어?" -> "없구나!" -> '잠시 이 사용자한테 공지 좀 보내야지!' -> "너 보낸 메시지 있어?"(반복)

  • Non-Blocing 문제인 반복적 시스템 콜 호출을 해결하기 위해 I/O 이벤트 통지 모델이 도입되었다.
    이벤트란 수신 버퍼출력 버퍼에 데이터를 처리하는 동작을 의미한다.

수신 버퍼의 이벤트 -> 입력 버퍼에 데이터가 수신되었다는 것을 알림 출력 출력 버퍼의 이벤트 -> 출력 버퍼가 비었으니 데이터 전송이 가능한 상황을 알림

  • 카톡을 예시로 들면 non-blocking 방식 일시 "너 보낸 메시지 있어?"를 계속 물어봐야 한다. 하지만 이벤트 통지방식 사용 시 먼저 입력 버퍼에서 "사용자가 보낸 메시지가 있습니다"라고 알림(이벤트 통지 모델)을 준다면 계속 물어봐야 했던 그 시간을 카카오톡은 이제 효율적으로 사용할 수 있다. 의존성이 없어진다.

  • I/O 이벤트 통지방식에는 동기/비동기 모델로 분류 가능하다.
    I/O 작업 상황(결과) 반환 방식에 따라 동기, 비동기 방식으로 분류된다.


동기(Synchronouse) 
Model이란

  • I/O 작업이 진행되는 동안 유저 프로세스는 결과를 기다렸다가 이벤트(결과)를 직접 처리하는 방식이다.

  • 이때 유저 프로세스는 blocking 방식처럼 다 될 때까지 기다릴 수도 있고, non-blocking처럼 커널에 계속 요청하는 방식으로 기다릴 수도 있다. 여기서 요점은, **'오매불망이던, 딴짓을 하면서든 결국은 기다린다'**는 것이다.

  • 결국 notify를 유저 프로세스가 담당하여 주체적으로 진행하며, 커널은 유저 프로세스의 요청에 수동적으로 응답한다.

비동기(Asynchronous) Model이란

  • I/O 작업이 진행되는 동안 유저 프로세스는 관심이 없다. 그저 자신의 일을 하다가 이벤트 핸들러에 의해 알림이 오면 처리하는 방식이다.

  • 결국 notify를 커널이 담당하여 주체적으로 진행하며, 유저 프로세스는 수동적인 입장에서 통지가 오면 그때 I/O 처리를 한다. (이벤트 핸들러, callback)에 의해 운영체제에서 처리 결과 통지받는다.

  • 결론
    • 블로킹(Blocking): I/O 작업 기다림 O / 대기 큐 stay O
    • 논블로킹(Non-Blocking): I/O 작업 기다림 O / 대기 큐 stay X
    • 동기(Synchronous): I/O 작업 기다림 O / 대기 큐 stay X
    • 비동기(Asynchronous) : I/O 작업 기다림 X / 대기 큐 stay X

(논블로킹과 동기 모델의 차이는 수신, 출력 버퍼에 notify(직접 호출, Callback 호출 차이)

 

  • 기타
    • I/O Multiplexing 은 select의 호출만을 떼어서 말하면 일단 OS 수준에서 Sync 방식인 것은 자명하지만,
      Sync-Blocking인지 Sync-NonBlocking 인지는 구현 방식에 따라 달라지므로 어느 한쪽이 맞다고 하기 어렵다.

    • 하지만, 보통 I/O Multiplexing이라고 하면 미시적으로 select의 호출 부분만을 말하는 것이 아니라, select의 대상이 되는 channel과의 연계까지도 포함하여 언급하려는 의도가 있다고 볼 수 있다. 그리고 이 과정에서의 channel은 NonBlocking 채널을 말한다.
      (Multiplexing, channel은 추후 블로그 글에서 정리할 예정이다.)

  • 참조

+ Recent posts