프로세스와 스레드
프로그램 실행의 기본 단위이다. 면접 단골 질문이기도 하다.
프로세스
프로세스는 실행 중인 프로그램의 인스턴스이다. 운영체제로부터 독립된 메모리 공간을 할당받는다.
메모리 구조
- Code: 컴파일된 기계어 코드. 읽기 전용.
- Data: 전역 변수, 정적 변수.
- Heap: 동적 할당 영역. 위쪽으로 성장.
- Stack: 함수 호출 정보. 아래쪽으로 성장.
스레드
스레드는 프로세스 내 실행 흐름의 단위이다. 하나의 프로세스는 최소 하나의 스레드를 가진다.
공유하는 것 vs 독립적인 것
| 공유 | 독립 |
|---|---|
| Code, Data, Heap | Stack |
| 파일 디스크립터 | PC, 레지스터 |
Stack만 독립적인 이유
Stack에는 함수 실행 흐름 정보가 담긴다.
- 돌아갈 주소 (Return Address)
- 지역 변수
- 매개변수
Stack을 공유하면 한 스레드가 함수 호출 시 다른 스레드의 리턴 주소를 덮어쓴다. 독립적인 실행 흐름을 위해 Stack은 분리되어야 한다.
프로세스 vs 스레드
| 구분 | 프로세스 | 스레드 |
|---|---|---|
| 메모리 | 독립 | 공유 (Stack 제외) |
| 생성 비용 | 큼 | 작음 |
| 컨텍스트 스위칭 | 느림 | 빠름 |
| 통신 | IPC 필요 | 직접 접근 |
| 안정성 | 높음 | 낮음 |
멀티 프로세스
하나의 프로그램을 여러 프로세스로 구성한다.
장점
- 한 프로세스가 죽어도 다른 프로세스 무관
- 메모리 침범 불가
단점
- IPC 필요
- 컨텍스트 스위칭 비용 큼
- 메모리 사용량 큼
예시: 크롬 브라우저 (탭마다 별도 프로세스)
멀티 스레드
하나의 프로세스 내에서 여러 스레드가 작업을 분담한다.
장점
- 메모리 공유로 통신 간편
- 컨텍스트 스위칭 비용 작음
단점
- 한 스레드 문제가 전체에 영향
- 동기화 문제 (Race Condition)
- 디버깅 어려움
예시: 웹 서버 (요청마다 스레드 할당)
자주 나오는 질문
스레드를 많이 만들수록 좋은가?
아니다. 코어 수를 초과하면 컨텍스트 스위칭이 빈번해진다.
- CPU 바운드: 코어 수와 비슷하게
- I/O 바운드: 코어 수보다 많이
멀티 프로세스 vs 멀티 스레드 선택 기준
| 상황 | 선택 |
|---|---|
| 안정성 중요 | 멀티 프로세스 |
| 빠른 통신 필요 | 멀티 스레드 |
| 메모리 제한적 | 멀티 스레드 |
| 독립적 작업 | 멀티 프로세스 |
크롬은 왜 탭마다 프로세스를 쓰는가?
- 한 탭이 죽어도 다른 탭 무관
- 탭 간 메모리 접근 불가 (샌드박싱)
- 탭 종료 시 메모리 완전 회수
실무 적용
스레드 풀
매 요청마다 스레드를 생성하면 오버헤드가 크다. 미리 만들어두고 재사용한다.
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(() -> { /* 작업 */ });스레드 로컬
각 스레드가 독립적인 변수를 가져야 할 때 사용한다.
ThreadLocal<User> currentUser = new ThreadLocal<>();
currentUser.set(user);
currentUser.get();