I/O에서 비동기와 동기 시나리오
🎯 시나리오: 웹 서버가 이미지 파일을 읽고 응답하는 상황 ** **🖼 목표 사용자가 /image.jpg를 요청하면, 서버는 디스크에서 image.jpg를 읽어 HTTP 응답으로 전송합니다.
1. 🔄 동기 I/O 처리 흐름
1
2
3
4
5
6
7
8
User -----> Server (GET /image.jpg)
↓
open image.jpg (동기)
↓
read from disk (I/O blocking)
↓
send HTTP response
- 서버는 요청을 받습니다.
- open() + read()를 사용하여 이미지 파일을 읽습니다.
- 이때 디스크 I/O가 발생하며, 프로세스는 대기 상태로 진입합니다.
- I/O가 완료되면 데이터를 메모리로 복사하여 응답을 생성합니다.
- 처리 중 다른 요청은 못 받습니다.
- 하나의 요청 처리에 스레드/프로세스가 블로킹됨
- 수천 개의 요청을 동시에 처리하려면 동일 수의 스레드가 필요함 (비효율)
2. ⚡ 비동기 I/O 처리 흐름 (epoll/io_uring 기반)
1
2
3
4
5
6
7
8
9
10
User -----> Server (GET /image.jpg)
↓
submit async read (등록만 함)
↓
continue handling other requests (이벤트 루프 지속)
↓
I/O 완료 시점에 콜백 or 이벤트 발생
↓
응답 전송
- 서버는 요청을 받자마자 image.jpg 비동기 읽기 요청을 OS에 전달 (epoll, io_uring, libuv 등 활용).
- 서버는 즉시 다음 요청을 처리합니다. (이벤트 루프 기반)
- 디스크에서 I/O가 완료되면, OS는 이벤트 알림을 통해 서버에 알려줍니다.
- 서버는 해당 요청을 다시 불러와 응답을 작성합니다.
- 수천 개의 클라이언트 요청을 하나의 스레드(혹은 소수의 스레드)로 처리 가능
- Node.js: 이벤트 루프 기반 비동기 구조
- FastAPI + uvicorn: Python의 async/await 지원
- Netty (Java): 비동기 네트워크 프로그래밍 프레임워크
✅ 정리: 비동기 I/O의 핵심 가치
| 항목 | 동기 I/O | 비동기 I/O |
|---|---|---|
| 응답 처리 | 블로킹 | 논블로킹 |
| 자원 활용 | 비효율적 | 효율적 |
| 동시성 처리 | 스레드 증가 필요 | 이벤트 루프로 가능 |
| 복잡도 | 낮음 | 높음 |
| 적합한 환경 | 단순 서비스 | 고부하 웹 서버, 실시간 채팅, 스트리밍 등 |
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.
