본문 바로가기

CS

sync / async & blocking / non-blocking

sync & async

synchronous라는 표현은 "동시에 실행된다"는 의미를 가지고 있다. 작업이 "동시에 실행된다"라고 해석하는 경우 동시성(Concurrent)이나 병렬(Parallelism)이 되는데, 이는 프로그래밍 언어에서 말하는 동기/비동기와는 다른 개념이다. sync나 async는 작업의 동시 실행이 아니라, 작업의 동기화(synchronization) 개념에 가깝다.

  • synchronous: 한 작업의 끝이 다른 작업의 시작과 동기화되어, 작업이 순서대로 실행된다.
  • asynchronous: 한 작업의 끝이 다른 작업의 시작과 동기화되지 않는다. 각 작업은 시스템 흐름(실행)과 독립적이다.
SYNCHRONOUS
   |--------A--------|
                     |--------B--------|

ASYNCHRONOUS
   |--------A--------|
         |--------B--------|

Sync 기반 프로그램은 A, B 작업의 시작과 끝이 동기화되어 순서대로 실행되고 종료된다. 이전 작업의 종료가 보장되어야 하거나 반환값이 필요할 때, 즉 작업의 순서가 보장되어야 할 때 사용된다.

반면 Async 기반 프로그램은 각 작업의 시작과 끝이 동기화되지 않으므로 실행 순서대로 종료되지 않을 수 있다. 각 작업의 종료나 결과에 관심이 없을 때 함께 실행하기 위해 사용한다.

blocking & non-blocking

blocking은 이름 그대로 다른 작업을 실행하기 위해 현재 실행 단위(스레드 / 메서드)를 멈추는지(block)를 의미한다.

  • blocking: 작업이 끝날 때까지 현재 실행 단위를 멈춤 ( 애플리케이션 정지 )
  • non blocking: 작업이 끝날 때까지 현재 실행 단위를 멈추지 않고 다른 작업 수행
BLOCKING
   |--------A--------|       대기      |--------A--------|
                     |--------B--------|

NON-BLOCKING
   |--------A--------|--------C--------|--------A--------|-------C-------|
                     |--------B--------|

 

Non-blocking이라는 표현은 보통 메인 스레드가 있는 이벤트 루프 시스템에서 자주 사용한다. 이 경우  Non-Blocking은 I/O 같이 시간이 오래 걸리는 작업이 등장할 때 실행 단위 = "스레드"가 해당 작업을 대기하지 않고 다른 작업을 수행한다는 의미로 사용된다. B 작업이 현재 스레드를 멈추게 하면 blocking, 아니면 non-blocking이 된다.

실행 단위의 경우 작업 또는 스레드로 해석될 수 있지만, Non-blocking을 강조하는 시스템은 대부분 실행 단위를 "스레드"로 이용하는 경우가 많다. Node.js나 Spring webflux는 Non-Blocking 시스템을 갖추고 있다고 설명한다. 여기서 Non-Blocking은 메인 스레드가 작업을 대기하지 않고 다른 작업을 계속 수행한다는 의미를 가지고 있다.

예를 들어 Node.js에는 async - await 문법이 있지만, 이를 blocking이라 표현하지 않는다. await 문법은 현재 메서드가 다른 작업이 종료되기를 대기하게 만들겠지만 (내부적으로는 promise로 처리됨), 메인 스레드는 메서드 작업과 상관 없이 다른 작업을 처리하기 때문이다.

정리

위 개념들에 대해 내가 이해한 바는 다음과 같다.

  • 동기 / 비동기는 "동기화 체계" 에 대한 설명. 여러 작업의 순서가 동기화되는가?
  • 블로킹 / 논블로킹: "대기"에 대한 설명. 현재 실행 단위 = 스레드가 다른 작업이 종료될 때까지 대기하는가?

동기 / 비동기는 작업 사이의 동기화 여부에 대해 설명한다. 작업의 시작과 끝이 동기화되서 순서대로 실행된다면 동기, 아니라면 비동기다. 싱글 / 멀티스레드와는 별개 개념으로, 싱글 스레드에서도 동시성(concurrent)을 통해 비동기 처리할 수 있다.

블로킹 / 논블로킹은 특정 작업이 현재 스레드를 멈추는지에 대해 설명한다. 작업이 스레드를 멈춰 다른 작업을 수행할 수 없다면 블로킹 작업이고, 작업이 스레드를 멈추지 않는다면 논블로킹 작업이다.

보통 blocking 메서드는 sync로, non-blocking 메서드는 async로 동작하는 경향이 있어 프로그래밍 언어나 시스템 수준에서 두 개념을 거의 동의어로 사용하는 경향이 많으며, 맥락마다 다른 의미를 가지고 있는 표현이기에 명확하게 구분되지도 않는다. 내가 속한 맥락에서 어떻게 해석하는지 찾아보고 사용하는 것이 가장 좋다고 생각한다.

'CS' 카테고리의 다른 글

AOP  (0) 2024.03.13
객체 지향 프로그래밍의 배경  (1) 2024.02.19
[CS] DIP / IoC / DI  (0) 2023.10.23
[CS] 객체 지향  (0) 2023.10.18
[batch] cron 표현식  (0) 2023.08.23