CS/Network

[네트워크] Blocking/Non-blocking & Synchronous/Asynchronous

bu119 2023. 7. 5. 23:40
728x90
반응형

동기/비동기는 우리가 일상 생활에서 많이 들을 수 있는 말이다.
Blocking과 Synchronous, 그리고 Non-blocking과 Asysnchronous를 서로 같은 개념이라고 착각하기 쉽다.


각자 어떤 의미를 가지는지 간단하게 살펴보자.

 

 

2대2 매트릭스로 정리된 그림이다.

 

그림을 보면 Blocking 이면 반드시 Sync 가 아니고, Non-blocking 이면 반드시 async 도 아니다. 즉, Blocking / Non-blocking 과 Sync / Async 는 다른 개념이라는 것이다.

Blocking / Non-blocking 과 Sync / Async 는 '관점'을 어떻게 두느냐에 따라 다르다.

 

블로킹 Blocking

  • A 함수가 B 함수를 호출 할 때, B 함수가 자신의 작업이 종료되기 전까지 A 함수에게 제어권을 돌려주지 않는 것

 

논블로킹 Non-blocking

  • A 함수가 B 함수를 호출 할 때, B 함수가 제어권을 바로 A 함수에게 넘겨주면서, A 함수가 다른 일을 할 수 있도록 하는 것.

 

동기 Synchronous

  • A 함수가 B 함수를 호출 할 때, B 함수의 결과를 A 함수가 처리하는 것.

 

비동기 Asynchronous

  • A 함수가 B 함수를 호출 할 때, B 함수의 결과를 B 함수가 처리하는 것. (callback)

 

Blocking / Non-Blocking

Blocking과 Non-Blocking은 다른 주체가 작업할 때 자신의 제어권이 있는지 없는지로 구분한다.

  • 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고서 호출한 함수에게 바로 돌려주지 않으면 Block
  • 호출된 함수가 자신이 할 일을 채 마치지 않았더라도 바로 제어권을 건네주어(return) 호출한 함수가 다른 일을 진행할 수 있도록 해주면 Non-block

 

호출된 함수에서 일을 시작할 때 바로 제어권을 리턴해주느냐, 할 일을 마치고 리턴해주느냐에 따라 Blocking과 Non-Blocking으로 나누어진다.

 

Blocking

Blocking은 자신의 작업을 진행하다가 다른 주체의 작업이 시작되면 다른 작업이 끝날 때까지 기다렸다가 자신의 작업을 시작하는 것을 의미한다.

🐶 : 고양이님 서류 전달드리겠습니다.
🐱 : 강아지님 서류 검토 끝날 때까지 기다리세요.

 

즉, 호출된 함수가 자신이 할 일을 모두 마칠 때까지 제어권을 계속 가지고서 호출한 함수에게 바로 돌려주지 않는 상황을 의미한다.

 

Non-Blocking

Non-Blocking은 다른 주체의 작업에 관련없이 자신의 작업을 하는 것을 의미한다.

🐶 : 고양이님 서류 전달드리겠습니다.
🐱 : 강아지님 서류 주고 가세요.

 

즉, 호출된 함수가 자신이 할 일을 모두 마치지 않았더라도 바로 제어권을 건네주어 호출한 함수가 다른 일을 진행할 수 있도록 해주는 상황을 의미한다.

 

Synchronous / Asynchronous

Sync와 Async는 결과를 돌려주었을 때 순서와 결과에 관심이 있는지 없는지로 판단한다.

즉, 신경을 쓰느냐 안쓰느냐의 차이다.

  • 호출된 함수의 수행 결과 및 종료를 호출한 함수가(호출된 함수뿐 아니라 호출한 함수도 함께) 신경 쓰면 Synchronous
  • 호출된 함수의 수행 결과 및 종료를 호출된 함수 혼자 직접 신경 쓰고 처리한다면(as a callback fn.) Asynchronous

 

동기/비동기는 일을 수행 중인 동시성에 주목하자.

즉, 호출된 함수(B)를 호출한 함수(A)가 신경쓰는지, 호출된 함수(B) 스스로 신경쓰는지를 동기/비동기라고 생각하면 된다.

비동기는 호출시 Callback을 전달하여 작업의 완료 여부를 호출한 함수에게 답하게 된다.

(Callback이 오기 전까지 호출한 함수는 신경쓰지 않고 다른 일을 할 수 있다.)

 

Synchronous (Sync)

Sync는 동기라는 뜻으로 작업을 동시에 수행하거나, 동시에 끝나거나, 끝나는 동시에 시작함을 의미한다.

🐶 : 고양이님 서류 전달드리겠습니다.
🐱 : 강아지님 기다리거나 다른 일을 하고 계세요. 강아지님 신경 끌게요~

(...서류 읽는 중)

🐱 : 강아지님 서류 이렇게 하세요.
🐶 : 고양이님 바로 처리하겠습니다.

 

즉, 호출된 함수의 수행 결과 및 종료를 호출한 함수와 함께 신경 쓰는 경우를 의미한다.

 

Asynchronous (Async)

Async는 비동기라는 뜻으로 시작과 종료가 일치하지 않고 끝나는 동시에 시작을 하지 않음을 의미한다.

🐶 : 고양이님 서류 전달드리겠습니다.
🐱 : 강아지님 기다리거나 다른 일을 하고 계세요. 강아지님 신경 끌게요~

(...서류 읽는 중)

🐱 : 강아지님 서류 이렇게 하세요
🐶 : 고양이님 나중에 내용을 확인하고 언젠가 처리하겠습니다.

 

즉, 호출된 함수의 수행 결과 및 종료를 호출된 함수 혼자 직접 쓰고 처리하는 경우를 의미한다.

 

4가지 개념을 바탕으로 혼합하기

 

 

위 그림처럼 총 4가지의 경우가 나올 수 있다.

좀 더 이해하기 쉽게 Case 별로 예시를 통해 보면서 이해하고 넘어가보자.

 

  • Blocking / Non-Blocking : 제어권을 안넘기는지 / 넘기는지
  • Sync / Async: 결과를 돌려줄 때 결과와 순서에 관심이 있는지 / 없는지

 

Sync + Blocking & Async + NonBlocking

우리가 가장 흔히 접할 수 있다.

 

 

Sync-Blocking

  • Synchronous + Blocking
  • 호출하는 함수는 호출된 함수의 작업 완료/리턴을 계속 기다린다.
  • 호출된 함수는 자신의 작업이 완료되면 리턴한다.

 

따라서 호출한 함수는 함수를 호출한 후, 리턴을 받기 전까지 다른 일을 하지 않고 대기한다.

 

Async-NonBlocking

  • Asynchronous + Nonblocking
  • 호출하는 함수는 호출된 함수의 작업 완료 및 리턴을 기다리지 않는다.
  • 호출된 함수는 호출되면 바로 리턴한다.

 

Sync + Non-Blocking

  • Synchronous + Nonblocking
  • 호출하는 함수는 호출된 함수의 작업 완료 및 리턴을 끝났는지 계속 기다린다.
  • 호출된 함수는 호출되면 바로 리턴한다.

 

  • Non-Blocking : 제어권을 넘김
  • Sync : 결과를 돌려줄 때 결과와 순서에 관심이 있음

 

따라서 호출한 함수는 호출 이후 제어권을 바로 받기 때문에 작업을 계속하면서, 호출했던 함수의 작업 완료는 주기적으로 확인한다.

 

호출되는 함수(B)는 결과를 처리하는대로 바로 반환하고, 호출하는 함수(A)는 작업 완료 여부를 신경을 쓰는 형태로 조합이 된다. 신경을 쓰는 방법으로는 기다리거나 물어보는 것 두 가지가 존재하나, Non-Blocking 함수를 호출했기 때문에 물어보는 작업만이 남는다.

따라서 호출되는 함수(B)가 바로 제어권을 돌려주며 호출한 함수(A)는 다른 작업을 수행할 수 있으나, 호출한 함수(A)는 호출되는 함수(B)의 결과를 처리해야하기 때문에 언제 종료되는지 알 수 없는 호출되는 함수(B)의 종료를 반복적으로 물어봐야한다는 의미다.

(호출한 함수(A)가 다른 작업을 수행할 수 있었음에도 불구하고 여전히 호출된 함수(B)의 결과에만 신경쓰기에 제 할 일을 못하게 되는 형태가 된다.)

 

 

🐶 : 고양이님 서류처리 부탁드립니다.
🐱 : 강아지님 다른 일을 하고 계세요.
🐶 : 네.
🐱 : (서류 처리 중)
🐶 : 고양이님 서류처리 끝났나요?
🐱 : 강아지님 아직이요.
🐶 : 고양이님 서류처리 끝났나요?
🐱 : 강아지님 아직이요.
🐶 : 고양이님 서류처리 끝났나요?
🐱 : 네.

 

Async + Blocking

  • Asynchronous + Blocking
  • 호출하는 함수는 호출된 함수의 작업 완료 및 리턴을 기다리지 않는다.
  • 호출된 함수는 자신의 작업이 완료되면 리턴한다.

 

  • Blocking : 제어권을 넘기지 않음
  • Async : 결과를 돌려줄 때 결과와 순서에 관심이 없음

 

호출한 함수는 호출한 함수의 리턴을 기다리지 않지만, 호출된 함수는 자신의 작업이 끝날 때까지 제어권을 넘겨 주지 않기 때문에 호출된 함수의 작업이 완료될 때까지 대기하게 된다.

즉, Sync-Blocking과 유사하게 동작하며, 이 방식에 비해 별다른 이점이 없다.

 

호출한 함수(A)는 호출되는 함수(B)의 작업 결과에 관심이 없음에도 불구하고 호출되는 함수(B)의 결과를 기다리고 있어야 하는 형태다.

 

 

🐶 : 고양이님 서류처리 부탁드립니다.
🐱 : 강아지님 처리가 끝날 때까지 기다리세요.
🐶 : 고양이님이 어떤 작업을 하던 저와는 관계없지만 기다릴게요.

 

이 조합은 큰 이점이 없어 이 방식을 사용할 필요는 없으나 의도치 않게 이 형태로 동작하는 경우가 있다고 한다.

Async-Nonblocking을 추구하다 의도치 않게 Async-Blocking이 되는 경우가 있다. 

다시 말해, 호출한 함수가 호출된 함수를 신경 쓰지 않고 다른 일을 하게 하도록 하고 싶은데, 어쩔 수 없이 호출된 함수를 기다리게 되는 경우이다.

 

대표적으로 Node.js와 MySQL의 조합에서 나온다고 한다.

 Node.js에서 Callback 지옥을 해치면서 Async로 전진해도, 결국 DB 작업 호출 시에는 MySQL에서 제공하는 드라이버를 호출하게 되는데, 이 드라이버가 Blocking 방식으로 동작하여 Async+Blocking 구조가 된다고 한다.

(Java의 JDBC도 동일하다.)

 

정리

 

우리가 흔히 말하는 동기/비동기는 Sync+Blocking과 Async+Non-Blocking 형태다.

그리고 추가적으로 Sync+Non-Blocking과 Async+Blocking 조합이 존재하는데,

개발할 때는 극히 드물겠지만 애플리케이션 자체에서 의도치 않게 이 두 가지 조합이 나올 경우가 있어서 알아두어야 한다.

조합된 각각의 단어의 의미를 생각해보면 어느정도 틀을 잡고 이해할 수 있다. 

제어권을 가지고 있느냐 없느냐 결과에 관심이 있느냐 없느냐를 기준으로 접근하여 살펴보면 된다.


 

참고 자료

https://steady-coding.tistory.com/531

https://musma.github.io/2019/04/17/blocking-and-synchronous.html

https://jh-7.tistory.com/25

https://velog.io/@maketheworldwise/SyncAsync-BlockingNon-Blocking-%EB%AC%B4%EC%8A%A8-%EC%B0%A8%EC%9D%B4%EC%9D%BC%EA%B9%8C

 

728x90
반응형