본문 바로가기
👨‍🏫일문일답

동기/비동기, 블로킹/논블로킹 이해하기

by 캔 2024. 1. 27.

동기(synchronous 또는 sync)는 한 작업을 수행하다가 다른 작업을 수행할 때 그 작업이 끝나고 나서 처음 작업을 다시 재개하는 방식을 말한다. 처음 작업은 새로운 작업이 끝나는 것을 "대기"한다. 반면에 비동기(asynchrnous 또는 async)는 한 작업을 수행하다가 다른 작업을 수행해도 처음 작업을 중단하지 않고 "동시"에 진행할 수 있다. 동기는 한 작업의 끝과 다른 작업의 시작이 일치한다(같다)고 이해할 수 있다.

 

한편, 블로킹은 한 작업을 수행할 때 다른 작업을 수행할 수 없는 상태 혹은 그 상태를 발생시키는 특성을 말한다. 다른 작업에 대한 "제어권"이 없기 때문에 블로킹이 일어난다. 반면에, 논블로킹은 블로킹이 발생하지 않는 상태 혹은 블로킹을 발생시키지 않는 특성을 말한다. 한 작업이 제어권을 독점하지 않고 다른 작업도 제어권을 가지기 때문에 작업을 동시에 진행할 수 있다.

 

블로킹이 발생한다는 것은 작업을 동시에 수행할 수 없으므로 결국 프로그램을 동기적으로 만든다. 그렇기 때문에 비동기 프로그래밍 코드에서 블로킹을 발생시키는 요소를 사용하는 것은 작업에 블로킹을 발생시키므로 비동기의 장점을 누릴 수 없게 된다.

 

반대로, 동기 프로그램에서 논블로킹 요소를 사용하는 경우, 논블로킹 요소를 동기처럼 사용하면 동기적으로 동작하도록 만들 수 있다. 예를 들면, 논블로킹 요소에 작업이 끝났는지 확인하거나 논블로킹 작업이 끝나야 다른 작업을 마치도록 하는 것과 같다. 이는 현재 작업을 반복적으로 블락시킨다.

 

인터넷에서 이 네 가지를 설명할 때 아래와 같은 매트릭스를 통해 설명하는 글이 많다. 그러면서 동기-논블로킹이니 비동기-블로킹이니 하면서 동기/비동기이면서 블로킹/논블로킹일 수 있는 것처럼 오해를 불러일으키는 방식으로 설명하곤 한다. 하지만, 위 그림에서 말하는 것은 동기 코드에서 논블로킹 요소를 사용하거나 비동기 코드에서 블로킹을 요소를 사용하는 등 사용 방법이 잘못된 사례를 가리키는 것이지 실제로 블로킹이면서 동기적이거나 논블로킹이면서 비동기적일 수는 없다.

 

정리해 보면, 블로킹이 발생하면 프로그램은 동기적일 수밖에 없다. 한 작업이 끝날 때까지 제어권이 없어 다른 작업을 수행할 수 없기 때문이다. 하지만, 논블로킹 요소를 사용할 경우 프로그램을 비동기적으로 "만들 수 있다." 여기서 중요한 것은 논블로킹 요소를 사용한다고 해서 프로그램이 비동기적으로 동작하지 않을 수도 있다는 것이다. 의도했을 수도 있고 아닐 수도 있다. 예를 들면, 다른 작업을 계속하면서 그 작업을 계속 트래킹해야 할 수도 있고, 아니면 개발자가 의도치 않게 그 작업이 끝나야 다음 작업을 수행하도록 했을 수도 있을 것이다. 그러므로 논블로킹 요소를 사용한다고 해서 반드시 비동기 프로그래밍이라는 목적을 달성할 수 없다는 것을 기억하자.