-
[Python] Async 핵심 개념 3부작 — 이벤트 루프, 동시성, 블로킹IT 2026. 1. 23. 11:19
이벤트 루프는 무엇을 하는가
async / await를 사용하다 보면 자연스럽게 이런 의문이 생깁니다.
이벤트 루프는 정확히 어떤 일을 하고 있을까?
이벤트 루프는 흔히 오해되듯이 “비동기 작업을 실행하는 엔진”이 아닙니다. 오히려 이벤트 루프는 작업을 언제 실행할지 결정하는 스케줄러에 가깝습니다.
이벤트 루프의 역할
이벤트 루프의 핵심 역할은 다음 세 가지로 정리할 수 있습니다.
- 실행 가능한 코루틴을 선택한다
- 실행이 불가능한 작업(I/O 대기 등)은 대기 상태로 둔다
- 준비가 된 작업이 생기면 다시 실행 기회를 준다
이 과정을 이벤트 루프는 끊임없이 반복합니다. 내부 구현은 복잡하지만, 개념적으로는 하나의 큰 반복문이라고 이해해도 무방합니다.
await의 의미
await는 단순히 “결과를 기다린다”는 의미가 아닙니다. await는 이 코루틴의 실행을 잠시 멈추고, 이벤트 루프에게 제어권을 돌려준다는 선언입니다.
이 선언 덕분에 이벤트 루프는 다른 코루틴을 실행할 수 있고, 프로그램 전체는 멈추지 않고 흘러갈 수 있습니다.
이벤트 루프는 무엇을 해결하는가
이벤트 루프는 CPU 성능을 극대화하기 위한 장치가 아닙니다. 그 목적은 명확합니다.
- I/O 대기 시간 낭비를 줄이고
- 하나의 스레드로 많은 작업을 효율적으로 관리하는 것
이 관점을 잡으면 async 코드의 동작이 훨씬 자연스럽게 보이기 시작합니다.
동시성 vs 병렬성
동시성과 병렬성은 자주 혼용되지만, 엄연히 다른 개념입니다. 이 차이를 이해하지 못하면 async의 역할을 오해하게 됩니다.
병렬성(Parallelism)
병렬성은 여러 작업이 물리적으로 동시에 실행되는 것을 의미합니다. 멀티코어 CPU에서 각 코어가 다른 작업을 처리하는 상황이 대표적입니다.
동시성(Concurrency)
동시성은 여러 작업을 번갈아 실행하면서 동시에 처리되는 것처럼 보이게 하는 것입니다. 실제로는 한 시점에 하나의 작업만 실행될 수도 있습니다.
파이썬에서의 의미
파이썬의 async 모델은 병렬성을 제공하지 않습니다. 대신 동시성을 매우 효율적으로 제공합니다.
이벤트 루프는 여러 작업을 동시에 실행하지 않지만, 수많은 작업을 동시에 관리합니다. 그래서 네트워크 서버나 I/O 중심 프로그램에서 강력한 성능을 발휘합니다.
정리하면 다음과 같습니다.
- 병렬성: 동시에 실행
- 동시성: 동시에 다루기
async는 후자를 위한 도구입니다.
async 코드에서 블로킹이 왜 위험한가
async 환경에서 가장 흔하게 듣는 조언은 이것입니다.
블로킹 코드를 넣지 마세요.
이 말은 단순한 스타일 가이드가 아니라, 프로그램 전체를 멈출 수 있는 경고입니다.
블로킹이란 무엇인가
블로킹 코드는 실행되는 동안 제어권을 반환하지 않는 코드입니다. time.sleep()이나 동기 I/O 함수들이 대표적인 예입니다.
이 코드들이 실행되는 동안 이벤트 루프는 아무 일도 할 수 없습니다.
왜 치명적인가
이벤트 루프는 모든 코루틴이 자발적으로 양보할 것이라는 전제 위에서 동작합니다. 그런데 하나의 블로킹 코드가 등장하면 이 전제가 깨집니다.
그 결과:
- 다른 코루틴들은 실행 기회를 잃고
- I/O가 준비되어 있어도 처리되지 않으며
- 전체 프로그램이 멈춘 것처럼 보이게 됩니다
안전한 async 코드를 위한 원칙
- I/O 작업은 반드시 비동기 라이브러리를 사용한다
- CPU 연산은 이벤트 루프 밖에서 처리한다
- await는 선택이 아니라 약속이다
이 원칙을 지키면 async 코드는 훨씬 예측 가능하고 안정적으로 동작합니다.
마무리
이 세 가지 개념은 각각 독립적으로 보이지만, 실제로는 하나의 흐름으로 이어져 있습니다.
- 이벤트 루프는 실행 시점을 관리하고
- 동시성은 그 관리 방식이며
- 블로킹은 그 구조를 무너뜨리는 요소입니다
이 구조를 이해하면, async는 더 이상 복잡한 문법이 아니라 명확한 실행 모델로 보이기 시작합니다.
'IT' 카테고리의 다른 글
[Python] 왜 Asyncio에는 Executor가 필요한가 — Async와 Cpu-bound의 경계 (0) 2026.01.23 [Python] 이벤트 루프는 어떻게 동작하는가 — Pseudo-code로 보는 Asyncio의 내부 (1) 2026.01.23 [Python] GIL — 파이썬은 왜 멀티코어를 막아놓았을까 (0) 2026.01.23 [Python] 서브루틴과 코루틴 — 흐름을 누가 쥐고 있는가 (1) 2026.01.23 [Python] abc 모듈과 추상 메서드 — 규칙을 코드로 표현하는 방법 (0) 2026.01.23