동기/비동기 & 블로킹/논블로킹 4가지 조합 상세 설명
소프트웨어 아키텍처의 핵심 개념인 동기/비동기 및 블로킹/논블로킹의 4가지 조합에 대해 설명합니다. 각 모델을 커피숍 주문에 비유하여 쉽게 이해하고, 기술적인 동작 방식과 특징을 분석합니다.
핵심 개념 정의
이 조합을 이해하려면 두 가지 관점을 분리해서 생각해야 합니다.
-
동기(Synchronous) / 비동기(Asynchronous): '작업 완료를 누가 확인하고 신경 쓰는가'의 관점입니다.
- 동기(Sync): 작업을 요청한 쪽(Application)이 직접 작업이 끝날 때까지 기다리거나, 계속 확인하며 결과물을 챙깁니다.
- 비동기(Async): 작업을 요청한 쪽(Application)은 요청만 하고 바로 다른 일을 합니다. 작업이 완료되면 작업을 처리한 쪽(Kernel 또는 다른 스레드)이 결과물을 사용할 수 있다고 알려줍니다(Callback, Event 등).
-
블로킹(Blocking) / 논블로킹(Non-Blocking): '요청한 작업을 기다리면서 내(Application)가 다른 일을 할 수 있는가'의 관점입니다. 즉, '제어권'이 누구에게 있는가 입니다.
- 블로킹(Blocking): 작업을 요청하면, 그 작업이 끝날 때까지 요청한 쪽(Application)은 멈춰서 아무것도 못 하고 대기합니다. 제어권이 넘어갑니다.
- 논블로킹(Non-Blocking): 작업을 요청하면, 작업 완료 여부와 상관없이 즉시 제어권을 돌려받아 다른 일을 할 수 있습니다.
4가지 조합 상세 설명
1. 동기-블로킹 (Synchronous-Blocking)
- 커피숍 비유: 키오스크에서 커피를 주문하고, 그 자리에서 커피가 나올 때까지 아무것도 안 하고 멍하니 서서 기다립니다.
- 동작 방식:
- 애플리케이션이 커널에 I/O 작업을 요청합니다 (함수 호출).
- 커널은 작업을 시작하고, 애플리케이션은 제어권을 커널에 넘겨준 채 멈춥니다 (Blocking).
- 커널이 작업(예: 파일 읽기)을 완료하고 결과 데이터를 반환합니다.
- 그제야 애플리케이션은 제어권과 결과 데이터를 돌려받고 다음 코드를 실행합니다.
- 특징:
- 가장 간단하고 직관적인 모델입니다.
- 요청한 작업이 끝날 때까지 시스템 전체가 멈출 수 있어, 자원 활용 효율이 매우 낮습니다.
- 대부분의 기본적인 파일 I/O, 네트워크 소켓 함수들이 이 방식으로 동작합니다.
2. 동기-논블로킹 (Synchronous-Non-Blocking)
- 커피숍 비유: 키오스크에서 커피를 주문하고, "아직 안 나왔나요?"라고 10초에 한 번씩 계속 물어봅니다. 물어보는 사이사이 잠깐 다른 생각(다른 일)을 할 수는 있지만, 커피가 나왔는지 계속 신경 써야 합니다.
- 동작 방식:
- 애플리케이션이 커널에 I/O 작업을 요청합니다.
- 커널은 작업을 즉시 처리할 수 없으면, "아직 준비 안 됨"이라는 상태를 즉시 반환합니다. 애플리케이션은 제어권을 잃지 않습니다 (Non-Blocking).
- 애플리케이션은 다른 일을 하다가, 주기적으로 커널에 "작업 끝났니?"라고 계속 물어봅니다 (Polling).
- 커널이 작업 완료하면, 애플리케이션의 질문에 결과 데이터를 반환합니다.
- 특징:
- 블로킹 상태에 빠지지는 않지만, 애플리케이션이 계속해서 작업 완료 여부를 확인해야 하므로 CPU 자원을 낭비하게 됩니다.
- 구현이 복잡해지고, 불필요한 호출이 많아질 수 있습니다.
3. 비동기-블로킹 (Asynchronous-Blocking)
- 커피숍 비유: 키오스크에서 커피를 주문하고 진동벨을 받습니다(비동기). 하지만 그 진동벨을 뚫어져라 쳐다보며, 울릴 때까지 다른 아무것도 하지 않고 그 자리에서 기다립니다.
- 동작 방식:
- 애플리케이션이 커널에 비동기 작업을 요청합니다. 커널은 즉시 반환하여 제어권을 애플리케이션에 넘겨줍니다.
- 애플리케이션은 작업 완료 신호(Signal)를 기다리는 다른 블로킹 함수를 호출합니다.
- 결국 애플리케이션은 작업 완료 신호가 올 때까지 멈춰 있습니다 (Blocking).
- 커널이 작업을 완료하고 신호를 보내면, 그제야 블로킹이 풀리고 다음 작업을 수행합니다.
- 특징:
- 거의 사용되지 않는 비효율적인 조합입니다. 비동기의 장점(다른 일을 할 수 있음)과 블로킹의 단점(기다려야 함)이 합쳐진 형태입니다.
- 여러 개의 I/O 작업을 동시에 요청하고, 그중 하나라도 완료될 때까지 기다려야 할 때
select, poll 같은 함수에서 사용될 수 있습니다.
4. 비동기-논블로킹 (Asynchronous-Non-Blocking)
- 커피숍 비유: 키오스크에서 커피를 주문하고 진동벨을 받습니다(비동기). 그리고 자리에 가서 편하게 책을 읽거나 다른 일을 합니다(논블로킹). 진동벨이 울리면 그때 커피를 받으러 갑니다.
- 동작 방식:
- 애플리케이션이 커널에 I/O 작업을 요청하고, 제어권을 즉시 돌려받습니다 (Non-Blocking).
- 애플리케이션은 자신의 다른 작업을 자유롭게 수행합니다.
- 커널은 백그라운드에서 요청된 작업을 처리합니다.
- 작업이 완료되면, 커널은 미리 약속된 방법(Callback 함수 호출, 이벤트 발생 등)으로 애플리케이션에 작업 완료를 통지합니다 (Asynchronous).
- 애플리케이션은 통지를 받고 결과 데이터를 처리합니다.
- 특징:
- 가장 효율적이고 확장성 높은 모델입니다.
- 제어권을 뺏기지 않고, 작업 완료 여부를 계속 확인할 필요도 없어 자원 낭비가 없습니다.
- Node.js, Netty, Nginx 등 현대적인 고성능 서버들이 이 모델을 기반으로 동작합니다.
- 전통적인 동기-블로킹 방식에 비해 코드의 흐름이 복잡하고 디버깅이 어려울 수 있습니다.
요약 테이블
| 조합 (Combination) | 제어권 반환 (Control Return) | 결과 처리 (Result Handling) | 커피숍 비유 |
|---|
| Sync-Blocking | 작업 완료 후 반환 | 직접 기다려서 결과 받음 | 커피 나올 때까지 카운터에서 대기 |
| Sync-Non-Blocking | 즉시 반환 | 직접 계속 물어봐서 결과 받음 | 10초마다 "다 됐나요?" 물어보기 |
| Async-Blocking | 즉시 반환 | 신호 올 때까지 대기 | 진동벨만 뚫어져라 쳐다보기 |
| Async-Non-Blocking | 즉시 반환 | 신호 오면 결과 처리 | 진동벨 받고 자리에서 다른 일 하기 |