핵심 요약
프로세스는 독립된 메모리 공간을 가진 실행 단위, 스레드는 한 프로세스 안에서 메모리를 공유하며 도는 실행 흐름이다. 스레드는 공유 덕에 통신이 빠르고 가볍지만, 같은 메모리를 동시에 건드려 경쟁 상태(race condition)가 생긴다. 프로세스는 격리돼 안전하지만 통신·전환 비용이 크다.
1. 무엇을 공유하고 무엇을 나누나
| 자원 | 프로세스 | 스레드 |
|---|---|---|
| 코드/힙 | 독립 | 공유 |
| 스택/레지스터 | 독립 | 각자 |
| 통신 방식 | IPC(파이프·소켓 등) | 공유 메모리 |
| 하나가 죽으면 | 다른 프로세스 영향 없음 | 프로세스 전체 위험 |
2. 동시성 vs 병렬성
- 동시성(concurrency) — 여러 작업을 번갈아 처리해 "동시에 진행되는 것처럼" 보이게 함(코어 1개로도 가능)
- 병렬성(parallelism) — 여러 코어에서 실제로 같은 순간에 실행
3. 언제 멀티스레딩, 언제 멀티프로세싱
- I/O 바운드(네트워크·디스크 대기 많음) → 스레드/비동기가 유리. 대기 중 다른 일 처리
- CPU 바운드(계산 많음) → 프로세스로 코어를 나눠 병렬 처리. 특히 Python은 GIL 때문에 스레드로는 CPU 병렬이 안 돼 멀티프로세싱을 씀
4. 경쟁 상태와 동기화
// 두 스레드가 동시에 count++ 하면
// 읽기→더하기→쓰기 사이에 끼어들어 값이 유실됨
lock.acquire()
count += 1 // 임계 구역
lock.release()
공유 자원을 건드리는 구간(임계 구역)은 뮤텍스·세마포어로 보호한다. 과하면 데드락, 부족하면 데이터 깨짐.
5. 면접 팁
- "스레드는 메모리 공유 → 가볍지만 위험, 프로세스는 격리 → 안전하지만 비쌈" 한 축으로 설명
- 컨텍스트 스위칭 비용이 프로세스가 더 큰 이유(메모리 맵·캐시 교체)를 덧붙이면 좋다
자주 묻는 질문
스레드가 프로세스보다 항상 빠른가요?
생성·전환 비용은 스레드가 쌉니다. 하지만 CPU 바운드 작업에서 Python처럼 GIL이 있으면 스레드로 병렬 계산이 안 돼 오히려 멀티프로세싱이 빠릅니다. 작업 성격(I/O냐 CPU냐)이 기준입니다.
경쟁 상태는 어떻게 알아채나요?
"가끔" 값이 틀리거나 재현이 안 되는 버그가 전형적 신호입니다. 공유 변수를 락 없이 여러 스레드가 쓰는 곳을 의심하고, 임계 구역을 뮤텍스로 감싸거나 불변 데이터·메시지 패싱으로 공유 자체를 줄입니다.
코루틴(async)은 스레드와 뭐가 다른가요?
코루틴은 한 스레드 안에서 협력적으로 양보(await)하며 도는 방식이라 컨텍스트 스위칭·락 비용이 거의 없습니다. I/O 대기가 많은 작업에 특히 효율적이지만, CPU를 오래 잡는 코드는 이벤트 루프를 막습니다.

댓글 0