정의
동기/비동기와 블로킹/논블로킹은 작업 처리 방식을 설명할 때 자주 함께 등장하는 개념이다.
두 개념은 비슷해 보이지만 구분 기준이 다르다.
- 동기/비동기: 작업이 순차적으로 진행되는지, 결과를 언제 어떻게 받는지에 대한 구분이다.
- 블로킹/논블로킹: 작업을 호출한 이후 제어권이 호출자에게 존재하는지에 대한 구분이다.
즉, 동기/비동기는 작업 흐름의 순서와 결과 통보 방식에 가깝고, 블로킹/논블로킹은 호출 이후 실행 흐름의 제어권이 어디에 있는지에 가깝다.
동기와 비동기
동기와 비동기는 작업이 순차적으로 진행되는지에 따라 구별된다.
좀 더 정확히는 작업 흐름의 순서와 결과 통보 방식에 대한 구분이다.
동기
동기(Synchronous)는 요청한 작업이 완료될 때까지 호출자가 대기하고, 해당 작업이 끝난 이후에 다음 작업을 순차적으로 진행하는 방식이다.
흐름은 다음과 같다.
요청 -> 결과 대기 -> 결과 획득 -> 다음 작업
동기 방식에서는 호출한 작업의 결과가 나와야 다음 흐름으로 넘어갈 수 있다.
비동기
비동기(Asynchronous)는 호출자가 작업을 요청한 뒤 결과를 기다리지 않고 바로 다른 작업을 요청하거나 수행할 수 있는 방식이다.
인터럽트처럼 요청을 보내고 다른 작업을 수행하다가, 결과가 준비되면 신호를 받는 방식으로 이해할 수 있다.
흐름은 다음과 같다.
요청 -> 바로 다음 작업 수행 -> 결과가 준비되면 통보받음
결과 통보 방식은 콜백, 이벤트, Future, Promise 등으로 구현될 수 있다.
블로킹과 논블로킹
블로킹과 논블로킹은 작업을 호출한 이후 제어권, 즉 실행 흐름이 호출자에게 존재하는지에 따라 구별된다.
블로킹
블로킹(Blocking)은 어떤 작업을 호출자가 요청한 후, 해당 작업이 종료될 때까지 제어권이 호출자에게 돌아오지 않는 방식이다.
즉, 요청자는 결과가 나올 때까지 blocked 상태로 대기한다.
대표적인 예시는 파일 읽기, 네트워크 통신, 스레드 종료 대기 등이 있다.
예를 들어 자식 스레드가 종료될 때까지 메인 스레드가 대기하는 코드는 블로킹 방식이다.
pthread_join(tid, NULL);
pthread_join을 호출하면 대상 스레드가 종료될 때까지 호출한 스레드는 대기한다.
논블로킹
논블로킹(Non-Blocking)은 어떤 작업을 호출자가 요청한 후 바로 제어권을 돌려받아 다른 작업을 수행할 수 있는 방식이다.
요청한 작업은 백그라운드에서 수행될 수 있고, 작업 완료 시 콜백이나 이벤트 등으로 통보받을 수 있다.
예를 들어 Java의 CompletableFuture는 별도의 스레드에서 작업을 비동기적으로 실행할 수 있다.
CompletableFuture.supplyAsync(() -> 작업());
이 경우 작업은 기본적으로 ForkJoinPool.commonPool의 별도 스레드에서 실행된다.
구분 기준
두 개념의 핵심 차이는 다음과 같이 정리할 수 있다.
| 구분 | 기준 |
|---|---|
| 동기/비동기 | 결과를 언제, 어떻게 받는가? 작업 흐름의 순서와 통보 방식 |
| 블로킹/논블로킹 | 제어권을 언제 돌려받는가? 작업 요청 후 대기 여부 |
동기/비동기와 블로킹/논블로킹 조합
동기/비동기와 블로킹/논블로킹은 서로 다른 기준이므로 조합해서 설명할 수 있다.
동기 블로킹
동기 블로킹은 호출자가 작업이 완료될 때까지 대기하는 방식이다.
작업 결과를 받아야 다음 작업으로 넘어가며, 그동안 제어권도 호출자에게 돌아오지 않는다.
가장 직관적인 방식이다.
요청 -> 대기 -> 결과 획득 -> 다음 작업
동기 논블로킹
동기 논블로킹은 호출자가 제어권을 바로 돌려받지만, 작업 결과가 필요할 경우 직접 확인하는 방식이다.
대표적으로 폴링(polling)이 있다.
호출자는 막히지 않고 계속 실행되지만, 결과를 확인하기 위해 반복적으로 상태를 조회한다.
요청 -> 제어권 반환 -> 상태 확인 반복 -> 결과 획득
비동기 블로킹
비동기 블로킹은 거의 사용되지 않는 조합이다.
작업이 순차적으로 수행됨을 보장하지는 않지만, 제어권은 호출 대상에게 양도하여 호출자가 대기하는 방식이다.
비동기 작업을 요청했음에도 호출자가 대기한다면 비동기의 장점이 줄어들기 때문에 일반적으로 자연스러운 조합은 아니다.
비동기 논블로킹
비동기 논블로킹은 호출자가 제어권을 즉각 돌려받고, 다른 작업을 수행할 수 있으며, 결과는 콜백이나 이벤트 등으로 통보받는 방식이다.
이벤트 기반 서버, JavaScript의 비동기 처리, 비동기 I/O 등에서 자주 사용된다.
요청 -> 제어권 반환 -> 다른 작업 수행 -> 결과 준비 시 통보
조합 요약
| 조합 | 설명 |
|---|---|
| 동기 블로킹 | 작업이 끝날 때까지 대기하고, 결과를 받은 뒤 다음 작업을 진행한다. |
| 동기 논블로킹 | 제어권은 바로 돌려받지만, 결과가 필요하면 직접 확인한다. |
| 비동기 블로킹 | 결과 통보 방식은 비동기적이지만, 호출자는 제어권을 넘기고 대기한다. |
| 비동기 논블로킹 | 제어권을 즉시 돌려받고, 결과는 콜백이나 이벤트로 통보받는다. |
정리
동기/비동기는 작업의 흐름과 결과 통보 방식에 대한 개념이다.
블로킹/논블로킹은 호출 이후 제어권이 호출자에게 바로 돌아오는지에 대한 개념이다.
따라서 두 개념은 같은 축이 아니며, 서로 조합해서 이해해야 한다.
가장 중요한 구분은 다음과 같다.
- 동기/비동기: 결과를 언제, 어떻게 받는가?
- 블로킹/논블로킹: 제어권을 언제 돌려받는가?