Search

blocking와 non-blocking, 동기와 비동기

I/O

I/O란 데이터의 입력(Input)과 출력(Output)을 일컫는 말이다. 일반적으로 I/O를 파일 I/O만 생각하는 경우가 많은데, 네트워크를 통해 데이터를 전송하거나 전송받는 것도 I/O에 포함된다. I/O의 두가지 방식인 Blocking I/O과 Non-Blocking I/O에 대해 알아보자.
I/O에 대해 알아보기 전에 동기(Asyncrounous), 비동기(Syncrounous)를 숙지하고 있어야 한다.

동기(Syncrounous)와 비동기(Asyncrounous)

간단하게 이해를 해보도록 하자, 동기라는 말과 같이 동기 방식의 경우 유저 프로세스(또는 쓰레드)가 요청한 작업에 대해 커널에 요청한 작업이 완료 될 때까지 기다리는 것을 뜻하며 비동기는 그와 반대로 기다리지 않고 다른 작업을 시작한다. 정도만 이해해두도록 하자.

Blocking I/O와 Non-Blocking I/O

대부분의 어플리케이션은 Blocking I/O를 채용하고 있다. Blocking I/O란 하나의 프로세스가 어떤 자원을 사용하고자 할 때 그 자원이 이미 사용되고 있다면, 그 프로세스의 자원이 사용이 끝날 때까지 기다리는 것을 말한다. 이러한 방식은 결국 다른 작업을 수행하지 못하고 대기하게 되므로 리소스 낭비가 된다.
카카오톡 채팅을 생각하면 쉽다.
"너 밥 먹었어?"
(답장이 올때까지 기다린다.)
"응 먹었어"
"왜 이제 대답해 기다렸잖아!"
전형적인 Blocking I/O로는 mysql을 예시로 들 수 있다. mysql은 I/O 처리가 될 때까지 유저 대기시킨다. 한번은 node.js에 mysql을 연동하였는데 비동기 Blokcing I/O Model 방식으로 동작하게 되었고 오류가 발생하였다. 그 이유는 mysql이 Blocking I/O로 동작하기 때문이다. node.js가 Non-Blocking I/O를 채택했더라도 연동된 라이브러리가 Blocking I/O라면 비동기 Blokcing I/O Model 방식으로 동작한다. 따라서 해당 부분에 대해 충분히 알아두어야 한다. 이런 문제는 Non-Blocking 방식으로 동작하는 mysql2 로 대체하면서 해결되었다.
Non-Blocking I/O 방식은 Blocking 방식의 문제점을 보완하기 위해 만들어졌다. 이 방식은 유저 프로세스 또는 쓰레드가 커널에 작업을 요청한다. 그 순간 바로 결과가 반환된다(결과 값이 있든 없든). 커널 작업이 완료가 되면 결과값을 유저에게 전달한다.
위와 같이 카카오톡 채팅을 예시로 들어보았다.
"너 밥 먹었어?"
(다른 일을 하며 기다린다.)
"응 먹었어"
"연락 없길래 나도 먹었어~"