
백엔드 개발자 채용공고를 확인하고 이력서를 넣어서 서류에 합격해 면접을 보게 되었습니다.
기본 인성관련 질문과 더불어 기술적인 프로그래밍 이론 또한 학습한 후, 면접 당일 면접 장소로 향했습니다.
면접 당일 마주한 내용 중 전혀 들어보지 못한 개념에 대해 질문을 받아 당황했고
"그 부분에 대해선 제가 지식이 부족합니다. 앞으로 학습할 수 있도록 하겠습니다."
라고 답변할 수밖에 없었습니다.
그 질문이 바로 오늘 이야기할 주제인
Blocking vs Non-blocking(블로킹 vs 논블로킹)과 Sync vs Async(동기 vs 비동기)
에 관련한 내용이었습니다. 앞에 사설이 길었으므로 아래 설명은 간단하게 해보겠습니다.
먼저 4가지 키워드를 하나씩 쪼개서 어떤 내용인지 살펴보겠습니다.
✅Blocking
Blocking(블로킹)은 작업을 제어할 수 있는 권한에 초점을 맞춰서 생각하면 편합니다.
어떤 작업을 진행(제어)하던 중인 주체 A와, 다른 또 하나의 주체 B가 작업을 실행하면 B의 작업이 끝날 때까지 대기했다가 B의 작업이 종료되고나서야 A의 작업을 다시 재개(제어)하는 것을 말합니다.
✅Non-Blocking
Non-Blocking(논블로킹)은 앞서 설명드린 블로킹과는 반대되는 개념으로, 다른 주체의 작업에 개의치 않고 자신의 작업 제어권을 가질 수 있는 것을 말합니다.
✅Sync(Synchronous)
프로그램에서 두 가지 이상의 메소드나 어플리케이션(편의상 메소드라고만 부르겠습니다.)이 서로 같은 시간에 시작하고 끝나거나 또는 하나의 메소드가 먼저 시작하고 끝났을 때, 바로 그 결과값을 이어받아 시작하는 것이 동기에 해당합니다.
그림으로 예를 들면 아래와 같이 두 가지 형태로 나타날 수 있습니다.


✅Async(Asynchronous)
비동기의 경우 앞서 설명드린 Sync와는 반대되는 개념으로 프로그램에서 두 가지 이상의 메소드가 서로에게 관여하지 않으며 말그대로 비동기적으로 실행되고 종료되는 것을 의미합니다.
그림으로 예를 들면 아래와 같은 형태가 될 수 있겠네요.

다음으로 각 키워드를 조합했을 때는 어떤 결과가 나타나는지 살펴보겠습니다.
✅Blocking + Sync(Synchronous)
앞서 확인한 Blocking은 다른 주체의 작업이 끝날때까지 기다렸다가 비로소 작업이 끝난 후에야 제 작업을 진행하는 것을 의미한다고 했고, Sync는 서로 같은 시간에 시작 및 종료하거나 어떤 한 어플리케이션, 메소드의 종료 시점에 맞춰 다른 메소드가 시작하는 걸 의미한다고 했습니다.
Java에서의 예시를 살펴보겠습니다.
public void methodA() {
String myMsg = methodB();
System.out.println(myMsg);
};
public String methodB() {
String msg = "Hello";
};
메소드 A는 메소드 B가 실행되고 결과값을 리턴해줘야만 실행되는 코드라고 가정합니다. 이것은 동기(Sync) 방식입니다.
우선 메소드 B가 실행되기 위해 제어권을 가져오게 됩니다. 메소드 B가 작업을 마친 뒤 결과값을 리턴하고 제어권을 메소드 A에게 전달합니다. 이것은 Blocking에 해당됩니다.
✅Non-Blocking + Sync(Synchronous)
이번엔 파이썬에서의 예시를 살펴보겠습니다.
device = IO.open()
ready = False
while not ready:
print("There is no data to read!")
# 다른 작업을 처리할 수 있음
# while 문 내부의 다른 작업을 다 처리하면 데이터가 도착했는지 확인한다.
ready = IO.poll(device, IO.INPUT, 5)
data = device.read()
print(data)
위 코드에서 알 수 있듯, while문이 진행되는 동안 자신의 작업을 처리(Non-Blocking)하면서, 결과가 리턴되면 while문을 빠져나와 device.read()를 실행(동기, Sync)하게 됩니다.
✅Non-Blocking + Async(Asynchronous)
위 조합의 대표적인 예는 JavaScript에서 API에게 요청을 보내고, 다른 작업을 진행하다가 콜백을 통해 추가적인 작업을 처리할 때 사용하는 것을 예로 들 수 있습니다.
fetch('url', option) .then((response) => {
return response.json();
})
.then((data) => {
doSomething(data);
});
✅Blocking + Async(Asynchronous)
이 조합은 왠만하면 개발자의 실수때문에 일어나는 조합이라고 합니다. 그만큼 효율이 좋지 않고 굳이 이 방식을 채택해야할 이유가 없기 때문입니다. 개발자가 Non-Blocking + Async를 조합해 사용하려다 실수로 Blocking + Async로 만들어버리는 경우가 있다고 합니다. 😂
대표적인 예시가 Node.js 와 MySQL로 구성한 프로젝트입니다.
Node.js로 구성한 프로그램이 callback 처리를 하며 비동기로 실행하고 있는데 DB를 MySQL로 채택하면 DB 작업 호출 시, MySQL에서 제공하는 드라이버를 호출하게 되는데, 이 때의 드라이버가 Blocking방식이라고 합니다.
[참고자료]
https://www.youtube.com/watch?v=oEIoqGd-Sns
https://velog.io/@codemcd/Sync-VS-Async-Blocking-VS-Non-Blocking-sak6d01fhx#21-blocking