쓰레드
쓰레드(Thread, 스레드)는 프로세스 내부의 실행 단위다. 하나의 프로세스는 하나 이상의 쓰레드를 가질 수 있으며, 쓰레드들은 *같은 메모리 공간(힙, 데이터, 코드)*을 공유하면서 각자의 스택과 레지스터를 따로 가진다. 동시성과 응답성을 구현하는 기본 도구다.
프로세스 vs 쓰레드
| 구분 | 프로세스 | 쓰레드 |
|---|---|---|
| 메모리 | 독립 | 공유 |
| 생성 비용 | 큼 | 작음 |
| 통신 | IPC 필요 | 변수 공유로 즉시 |
| 고장 파급 | 다른 프로세스에 영향 X | 같은 프로세스 전체 영향 |
쓰레드를 쓰는 이유
- 동시성: 여러 작업을 동시에 진행
- 응답성: UI와 백그라운드 작업 분리로 끊김 없는 경험
- 자원 활용: 멀티코어 CPU를 병렬로 사용
- 비동기 I/O: 대기 시간에 다른 일을 처리
쓰레드의 상태
| 상태 | 설명 |
|---|---|
| New | 생성됨, 아직 실행 전 |
| Runnable | 실행 준비 완료, 대기 중 |
| Running | CPU가 실행 중 |
| Blocked/Waiting | I/O·락 대기 |
| Terminated | 종료됨 |
동시성 문제
쓰레드가 메모리를 공유하기 때문에 발생하는 대표 문제들:
- 경쟁 상태(Race Condition): 순서에 따라 결과가 달라짐
- 교착 상태(Deadlock): 서로가 가진 자원을 기다리며 멈춤
- 기아 상태(Starvation): 특정 쓰레드가 계속 자원을 못 얻음
- 가시성 문제: 한 쓰레드의 변경이 다른 쓰레드에 안 보임
동기화 기법
- 뮤텍스(Mutex): 한 번에 하나만 접근
- 세마포어: N개까지 접근 허용
- 모니터/synchronized: 객체 단위 잠금
- 원자 연산(Atomic): 분할 불가능한 단일 연산
- 읽기-쓰기 락: 읽기는 공유, 쓰기는 배타
유저 쓰레드 vs 커널 쓰레드
| 구분 | 설명 |
|---|---|
| 유저 쓰레드 | 라이브러리 수준, 컨텍스트 스위칭 빠름 |
| 커널 쓰레드 | OS가 관리, 진정한 병렬 실행 가능 |
현대 언어는 둘을 혼합한다. 예: 자바의 가상 쓰레드, 고(Go)의 고루틴.
관련 노트
- 세션: 여러 쓰레드가 공유할 수 있는 사용자 맥락
- 시큐어 코딩: 동시성 취약점 대응
- Debugging: 쓰레드 버그는 재현이 어려움
- 소프트웨어 아키텍쳐: 동시성 모델은 아키텍처의 핵심