Notice
Recent Posts
Recent Comments
Link
변수의 기록
(os) 비동기(Asynchronous) 프로그래밍과 운영체제 관점의 이해 본문
📌 비동기(Asynchronous) 프로그래밍과 운영체제 관점의 이해
1. 비동기(Asynchronous)의 기본 개념
비동기(Asynchronous)란 작업의 수행 순서가 반드시 직렬적일 필요가 없는 처리 방식이다. 요청을 보낸 후 그 결과가 도착할 때까지 대기하지 않고, 다른 작업을 수행하거나 나중에 콜백/이벤트로 결과를 받아 처리한다.
즉, 비동기 프로그래밍은 독립적이다. 한 작업의 결과를 기다리지 않아도 다른 작업을 병렬로 진행할 수 있다.
2. 비동기의 다양한 쓰레드 모델 예시
아래는 비동기 프로그램이 어떻게 다양한 쓰레드 모델로 구현될 수 있는지를 설명한 사례다.
- (1) 쓰레드 1개에 1작업 (기본 싱글 스레드 모델)
- 구조: 하나의 쓰레드가 하나의 작업을 수행
- 대표 사례: JavaScript, Node.js (이벤트 루프 기반)
- 특징:
- CPU-bound 작업엔 비효율적일 수 있지만
- I/O 작업이 많은 환경에서는 논블로킹 I/O를 이용한 이벤트 기반 처리로 매우 효율적
- 장점:
- 컨텍스트 스위칭이 없음 → 오버헤드 최소화
- 단점:
- 병렬 처리 어려움, 오직 논블로킹 환경에서만 확장성 확보
(2) 쓰레드 4개에 각 1작업 (전형적인 병렬 처리 구조)- 구조: 작업 수 = 쓰레드 수 → 1:1 매핑
- 특징:
- 각 작업이 블로킹이라도 상관 없음 (쓰레드 독립)
- 멀티코어 CPU에서 병렬로 실행됨
- 장점:
- 직관적이고 안정적인 처리
- 단점:
- 많은 쓰레드를 생성할 경우 스케줄링 비용(컨텍스트 스위칭), 메모리 사용량 증가
- 많은 쓰레드를 생성할 경우 스케줄링 비용(컨텍스트 스위칭), 메모리 사용량 증가
-
- 핵심 포인트:
- 쓰레드 하나가 논블로킹 I/O 작업을 던져놓고 다음 동기 작업을 수행
- 다른 쓰레드는 그와 별개로 병렬 작업을 수행
- 장점:
- 적은 쓰레드로도 높은 처리량 확보
- 동기/비동기 병행이 유연하게 가능
- 단점:
- 구조 복잡성 증가 (콜백 지옥, 흐름 추적 어려움)
(4) 쓰레드 1개에 2작업 (이벤트 루프 기반 처리)- 구조: 하나의 쓰레드가 여러 작업을 관리 (주로 I/O 중심)
- 처리 방식:
- 작업 요청 → I/O는 OS에 위임 → 제어권 반환
- 완료 시점에 이벤트 루프가 해당 콜백을 처리
- 예: Node.js, Netty
- 장점:
- 쓰레드 수 최소화 → 리소스 절약
- 단점:
- CPU-bound 작업이 끼어들면 전체 흐름 정체 가능
- 병렬성이 아닌 동시성 기반 모델
- 핵심 포인트:
(3) 쓰레드 2개로 4작업 분할 (Sync + Async 혼합 모델)- 구조: 적은 수의 쓰레드로 여러 작업을 병렬 분할 처리
- 주요 전략:
- CPU 연산이 많은 작업은 블로킹(동기) 처리
- I/O 중심 작업은 논블로킹(비동기) 처리
- 예시:
- Spring WebFlux (reactive async)
- 일부 API는 RestTemplate 등 동기 방식으로 호출
3. 비동기를 가능하게 하는 두 가지 핵심 기술
비동기를 구현하기 위한 핵심은 다음 두 가지다:
(1) 멀티스레딩 (Multi-threading)
- 프로세스 내에서 여러 스레드를 생성하여 동시에 여러 작업을 처리할 수 있음
- CPU-bound 작업이나 I/O 대기 시간이 짧은 경우에 유리
- 자원 소비 많고, 스레드 수가 많을수록 스케줄링 비용 증가
(2) 논블로킹 I/O (Non-blocking I/O)
- I/O 요청 후 대기하지 않고 즉시 제어권을 반환
- 실제 결과는 준비되었을 때 이벤트 루프가 알려줌
- 적은 수의 쓰레드로도 많은 작업을 처리 가능 → 처리량(Throughput) 극대화
결론적으로, **"스레드를 적게 유지하면서 Non-blocking을 활용하는 구조가 전체 처리량을 높이는 핵심"**이다.
예: Reactor, Netty, Node.js
4. Synchronous I/O vs Asynchronous I/O
구분 | Synchronous I/O | Asynchronous I/O |
처리 방식 | I/O 완료까지 호출자가 대기 | 호출 즉시 반환, 나중에 알림 수신 |
자원 효율 | 낮음 (쓰레드 블로킹됨) | 높음 (리액티브, 이벤트 기반) |
적용 사례 | 간단한 REST API, 일괄 처리 | 고성능 서버, 스트리밍 서비스 |
알림 방식 | 직접 결과 리턴 | 콜백, Future, Promise, Event |
예시로 비동기 I/O를 사용하는 시스템은 이벤트 큐 기반으로 동작하며, I/O가 완료되면 OS 커널이나 라이브러리가 인터럽트나 이벤트로 알림을 준다.
5. 비동기의 아키텍처 활용: MSA + 메시지 큐
Microservices Architecture (MSA)에서는 비동기 메시징 시스템이 자주 활용된다.
- 예시: A 서버 → B 서버 → C 서버
직접 통신하지 않고 **메시지 큐(Kafka, RabbitMQ 등)**에 메시지를 넣어 비동기적으로 전달 - 장점:
- 느슨한 결합
- 장애 격리
- 확장성 확보
- 단점:
- 응답 지연 가능
- 트랜잭션 처리 복잡성 증가
하지만, 경우에 따라 동기 API 호출이 유리한 상황도 있다.
6. 언제 메시지 큐가 아니라 API 호출이 더 나은가?
메시지 큐 기반 비동기 처리보다, API 통신이 더 효율적인 경우가 있다:
- A 서버가 B 서버의 특정 데이터를 필요로 할 때
- 요청 → 응답 시간이 짧고 실시간성이 중요한 경우
- 비즈니스 로직 상, 결과를 즉시 확인해야 하는 경우
즉, 모든 상황에서 비동기가 정답은 아니며, 필요에 따라 비동기와 동기의 적절한 혼합이 중요하다.
'CS지식 > 운영체제 (Operating System)' 카테고리의 다른 글
(OS) Block I/O vs Non-block I/O (소켓 I/O 기반 설명) (0) | 2025.04.17 |
---|---|
(OS) Thread Per Request vs Thread Pool 모델 정리 (쓰레드 비교) (0) | 2025.04.15 |
(os) 커널이란 무엇인가? (예시 포함 아주 쉽게 설명) (0) | 2025.04.15 |
(OS) 스레드의 종류 (하드웨어, OS, 유저 , 그린 ,커널) (0) | 2025.04.14 |
(OS) 유저 모드와 커널 모드, 그리고 인터럽트와 시스템 콜 (예제 있음) (1) | 2025.04.13 |