"프로세스는 실행 중인 프로그램, 스레드는 그 안의 실행 흐름"이라는 정의는 외워도 와닿지 않습니다. 헷갈리는 핵심은 딱 하나, 메모리를 공유하느냐입니다. 여기서 격리·통신·비용이 전부 갈립니다.
핵심 차이는 메모리 공유
프로세스는 각자 독립된 메모리 공간을 가집니다. A 프로세스가 자기 변수를 바꿔도 B 프로세스는 전혀 모릅니다. 반면 한 프로세스 안의 스레드들은 같은 메모리(힙·전역변수)를 공유합니다. 그래서 스레드끼리는 변수로 바로 데이터를 주고받지만, 동시에 같은 값을 건드리면 깨지는 경쟁 상태(race condition)가 생깁니다.
| 구분 | 프로세스 | 스레드 |
|---|---|---|
| 메모리 | 독립 공간 | 같은 프로세스 내 공유 |
| 격리 | 강함 (하나 죽어도 영향 없음) | 약함 (하나 크래시 → 전체 위험) |
| 통신 방법 | IPC (파이프·소켓·공유메모리) | 변수·전역 메모리 직접 |
| 생성·전환 비용 | 큼 (메모리 공간 복제) | 작음 (스택만 별도) |
| 스택 | 각자 | 각자 (코드·힙은 공유) |
언제 무엇을 쓰나
- 안정성·격리가 우선이면 프로세스: 한 작업이 죽어도 나머지가 살아야 하는 구조(웹서버 워커 분리, 크롬 탭별 프로세스).
- 빠른 데이터 공유·가벼운 동시성이면 스레드: 같은 데이터를 여러 흐름이 함께 처리(이미지 일괄 변환, 요청 핸들러 풀).
리눅스 내부에서는 사실 둘 다 "태스크"로 다루며, fork()는 새 메모리 공간을, clone()은 메모리를 공유하는 흐름을 만듭니다. 스레드는 메모리를 공유하는 가벼운 태스크인 셈입니다.
직접 확인하기
프로세스 목록은 ps -ef, 스레드까지 펼치려면 -L을 붙입니다.
로컬 터미널
ps -eLf | head
OUTPUT
UID PID PPID LWP NLWP CMD
root 1234 1 1234 8 /usr/bin/myapp
root 1234 1 1235 8 /usr/bin/myapp
같은 PID(1234)인데 LWP(스레드 ID)가 다르고 NLWP가 8이면, 이 프로세스가 스레드 8개를 돌리고 있다는 뜻입니다. 특정 프로세스의 스레드만 보려면:
로컬 터미널
ps -T -p 1234 # 해당 PID의 스레드 나열
ls /proc/1234/task # 스레드별 디렉터리(LWP 단위)
top에서 H를 누르면 스레드 단위로 CPU 사용을 볼 수 있어, 어느 스레드가 CPU를 먹는지 추적할 때 유용합니다.
요점 정리
- 차이의 본질은 메모리 공유 여부 — 나머지는 여기서 파생됩니다.
- 프로세스 = 강한 격리·큰 비용·IPC 통신, 스레드 = 약한 격리·작은 비용·메모리 직접 공유.
- 스레드는 빠르지만 공유 메모리 동기화라는 대가가 따릅니다.
ps -eLf의LWP·NLWP로 스레드 구조를 눈으로 확인하세요.
프로세스·스레드를 ps·/proc·top으로 직접 들여다보는 실습은 리눅스 트랙에서 회원가입 없이 무료로 익힐 수 있습니다.