한 줄 정의
프로그램이 여러 작업을 처리하기 위해 구조화하는 방식(동시성), 하드웨어 멀티 코어를 통해 실제 물리적으로 동시에 실행하는 방식(병렬성), 그리고 스레드를 차단하지 않고 대기 중 유휴 시간을 생산적으로 활용하는 프로그래밍 모델(비동기)의 총체적 관계.
핵심 요지
- 롭 파이크(Rob Pike)의 정의: “동시성(Concurrency)은 여러 일을 한 번에 다루는(Dealing) 구조적 설계 방식이고, 병렬성(Parallelism)은 여러 일을 한 번에 처리하는(Doing) 물리적 실행 방식이다.”
- **비동기(Async)**는 단일 스레드에서도 이벤트 루프(Event Loop)를 활용해 대기 상태를 비차단(Non-blocking)으로 전환함으로써 높은 동시성을 달성하는 구체적인 개발 기법이다.
- 세 개념은 상호 배타적이지 않으며, 병목 지점이 연산 제한(CPU-bound)인지 혹은 입출력 제한(I/O-bound)인지에 따라 최적의 선택 전략이 달라진다.
상세
- 동시성 (Concurrency):
- 여러 작업이 논리적으로 동시에 진행 중임을 의미한다.
- 싱글 코어 환경에서는 시간 분할(Time-slicing) 및 문맥 전환(Context switching)을 통해 프로세서가 여러 작업을 고속 교대함으로써 동시 실행되는 것처럼 보이나, 실제 내부적으로는 한 순간에 한 명령만 처리된다.
- 반응성(Responsiveness) 향상에 유리하며, 주로 I/O-bound 작업에 적합하다.
- 병렬성 (Parallelism):
- 여러 작업이 물리적으로 정확히 같은 순간에 여러 CPU 코어에서 실행되는 상태다.
- 이미지 처리, 딥러닝 추론 등 연산 중심인 CPU-bound 작업에서 선형적인 성능 도약을 꾀할 수 있다.
- 두 개 이상의 코어가 공유 데이터에 접근하는 경우 경쟁 상태(Race Condition)가 유발되며, 뮤텍스(Mutex)나 세마포어(Semaphore) 등을 사용한 동기화로 인해 락 경합(Lock Contention) 오버헤드가 동반될 수 있다.
- 비동기 I/O (Async I/O):
- 단일 스레드가 차단(Blocking)되지 않고 대기(Wait)하는 비차단 방식의 프로그래밍 모델이다.
- 이벤트 루프와 상태 머신(State Machine) 지정을 활용하여, 대기 응답이 올 때까지 스레드를 풀어 다른 요청을 처리하게 한다.
- 스레드 생성 비용과 컨텍스트 스위칭 비용을 최소화하며 고성능 확장 서버를 구동하는 핵심 축이다.
예시
- 식당 주방에 비유한 개념 구분:
- 동시성(Concurrency): 셰프 1명이 물이 끓는 동안 채소를 썰고 소스를 젓는 등, 혼자 저글링하듯 여러 메뉴 준비 단계를 전환하는 상태.
- 병렬성(Parallelism): 주방에 셰프를 추가 고용하여 1명은 파스타를 삶고 다른 1명은 샐러드를 만드는 등, 물리적으로 다른 공간에서 진짜 동시에 작업하는 상태.
- 비동기(Async): 셰프가 오븐에 구이를 넣고 요리가 익을 때까지 오븐 앞에 멍하니 서 있는 것이 아니라, 테이블 서빙을 돌거나 예약 전화를 받는 등 비차단 대기를 구현하는 모델.
충돌
- 멀티 스레드 성능 만능론 vs 암달의 법칙 (Amdahl’s Law):
- 모든 프로그램이 병렬 코어를 늘린다고 무조건 빨라진다는 오해.
- 암달의 법칙에 따르면, 프로그램 중 오직 비율의 영역만 병렬화가 가능할 때 코어 개수 을 무한히 투입하더라도 속도 증가 는 로 한계가 지어진다. 병목을 유발하는 직렬화 코드 영역(상태 공유 락, 직렬 정렬 등)을 줄여야 병렬 코어 추가의 이점이 극대화된다.