이번에는 PCB와 TCB가 무엇인지 알아보도록 하자.
컨텍스트 스위칭을 할 때 PCB라는 자료구조를 갈아끼운다고 알고는 있는데 TCB는 무엇이고 어디서 어떻게 쓰는지 짧게 정리해 보았다.
PCB란?
Process Control Block의 약자로 운영체제가 프로세스(한 프로세스 단위의 실행 컨텍스트, 자원 집합)정보를 관리하기 위해 커널이 갖고 있는 데이터 구조를 의미한다.
PCB에는 다음과 같은 항목들이 들어간다.
- PID(프로세스 식별자)
- 프로세스 상태(new, ready, running, waiting, terminated)
- 메모리 정보 포인터(페이지 테이블, 주소 공간 정보 등)
- 파일 디스크립터 테이블 포인터 (열린 파일 목록)
- 시그널 핸들러 정보
- 게정/권한 정보(UID/GID)
- 부모/자식 프로세스 포인터(트리관계)
- 스케줄링 관련 정보(우선순위, 정책) - 보통 쓰레드 단위이지만 프로세스 단위 정보도 포함
- 프로세스 수준의 통계/계정(실행시간 등)
- 쓰레드 목록 포인터(프로세스에 속한 TCB들에 대한 링크)

TCB란?
Thread Control Block의 약자로 운영체제가 쓰레드(실행 단위 ,레지스터/스택 등)정보를 관리하기 위한 데이터 구조(쓰레드의 "실행 상태" 및 스케쥴링 정보)를 담고 있는 데이터 구조이다.
(TCB는 문맥에 따라 Task Control Block이라고 불리며, 네트워크에서는 Transmission Control Block을 뜻하기도 한다.)
TCB에 보통 들어가는 항목들
- TID(쓰레드/Task 식별자)
- 쓰레드 상태(running , ready, blocked 등)
- 레지스터 저장 영역(CPU 레지스터. PC, SP 등) - 문맥교환시 이곳에 저장/복원
- 커널 스택 포인터(스택 영역) - 커널 모드로 진입했을 때 사용할 스택
- 유져 스택 포인터(유져의 스택의 베이스/끝 포인터)
- 스케쥴링 정보(우선순위, timeslice, runqueue 노드)
- 쓰레드 로컬 저장소(TLS)포인터
- 소유 프로세스(PCB)로의 포인터
- 동기/잠금 관련 정보(블록된 이유, 대기 중인 락 등)
TCB는 "실제로 CPU에 올라가고 내려갈 때 필요한 모든 실행 컨텍스트"를 의미한다.

| 항목 | PCB | TCB |
| 단위 | 프로세스(자원 묶음) | 쓰레드(실행단위) |
| 저장내용 | 주소공간, 파일 테이블, 권한 등 | 레지스터, 스택, 스케쥴링 정보 |
| 수 | 보통 프로세스 당 1개 | 한 프로세스에 여러개 존재가능 |
| 문맥교환 비용 | 프로세스 전환은 보통 더 큰 비용(페이지 테이블 전환등) | 같은 프로세스 내 쓰레드 전환은 가벼움(메모리 맵 공유) |
| 공유자원 | 프로세스 내 쓰레드가 공유 | 쓰레드 자체는 자원 일부(스택) 비공유 |
생성 실행 종료 PCB TCB 연관 관계
프로세스 생성 (fork() -> execve 흐름)
1. fork호출
- 커널이 부모 PCB를 복사하거나 새로운 PCB를 할당
- 새 PID를 부여하고 부모/자식 관계를 연결
- 자원(파일 테이블 등)을 필요에 다라 복사하거나 공유
2. 새 프로세스는 하나 이상의 TCB 를 갖게 됨
- 프로세스가 단일 쓰레드이면 1개의 TCB생성
3. execve 호출시
- 기존 주소공간(페이지 테이블0을 해제/새로 구성 -> PCB 메모리 포인터 갱신
- 동일한 PCB(및 TCB)에서 프로그램 이미지가 변하면서, 레지스터/스택 초기화
쓰레드 생성
1. 사용자/라이브러리 호출 => 커널(또는 사용자 쓰레드 라이브러리)에 TCB할당
2. TCB 초기화 : 레지스터, 유저/커널 스택, TLS, 스케쥴링 우선순위 등 설정
3. TCB가 PCB를 가리킴
4. 스케쥴러의 ready queue에 넣음 => 나중에 CPU가 할당되면 해당 TCB의 문맥이 로드되어 실행
문맥 교환
문맥 교환은 쓰레드 혹은 프로세스가 CPU를 넘겨줄 때 발생한다.
1. 인터럽트/타이머/블록 발생 => 현재 CPU가 중단
2. 현재 쓰레드의 레지스터 값을 현재 TCB의 저장 공간에 저장(PC, SP, 일반 레지스터 등)
3. 현재 쓰레드 상태 갱신(running => ready/blocked)
4. 스케줄러 호출 : 다음 실행할 TCB 선택(run queue에서)
5. 만약 다음 쓰레드의 주소공간(mm)이 현재와 다르면 페이지 테이블 교체 => 프로세스 전환시 필요
6. 다음 쓰레드의 레지스터 값을 TCB에서 CPU레지스터로 복원 => 스택 포인터 등 포함
7. 커널/유저 모드 복귀 => 실행 재게
(같은 프로세스 내 쓰레드 간 전환은 5번(페이지 테이블 교체)을 건너뛰므로 더 빠르다)
스케줄러와 자료구조와의 관계
- run queue / ready queue : TCB(또는 PCB를 래핑한 스케쥴링 노드)가 들어있는 큐들.
- 우선순위 큐, 라운드 로빈, CFS 등 스케줄링 알고리즘은 TCB의 우선순위, 가중치, 남은 타임 슬라이스를 보고 결정.
- TCB/PCB는 보통 이 큐들의 노드(링크드 리스트 노드, 힙 인덱스 등)로도 사용된다.
커널 쓰레드 vs 사용자 레벨 쓰레드
- 커널 레벨 쓰레드 : 커널이 직접 관리하는 TCB가 존재 => 문맥 교환 시 커널이 직접 register 저장/복원
- 사용자 레벨 쓰레드(유져 레벨 쓰레드 라이브러리) : 커널은 하나의(또는 적읜 수의)커널 쓰레드만 보고, 유져 라이브러리가 자체적으로 유져공간 TCB를 관리한다.
장점 : 쓰레드 전환이 빠름
단점 : 블로킹 시스템 콜 시 전체 프로세스가 블록 될 수 있다.
요약
- PCB : 프로세스의 자원, 권환, 주소공간 등 프로세스 레벨 정보를 저장한다.
- TCB : 쓰레드의 레지스터, 스택, 스케쥴링 상태 등 실행 컨텍스트 저장
- 쓰레드 전환 < 프로세스 전환(비용면에서) => 같은 프로세스 내 쓰레드는 메모리 맵 공유로 더 가볍다.
- 커널은 이들 구조를 활용하여 생성/스케줄링/문맥교환/종료를 관리한다.
멀티쓰레드 환경에서 컨텍스트 스위칭시 쓰레드들은 같은 메모리를 공유하기때문에 TCB수준에서의 문맥만 저장 복원만 하면 되기때문에 상대적으로 문맥 교환 비용이 저렴하고(레지스터, 스택 포인터, 프로그램 카운터 등)
프로세스간 문맥 교환을 하게 되면 PCB 수준에서의 저장 복원의 작업(페이지 테이블 교체, TLB 무효화 등)이 들어가기 때문에 상대적으로 비용이 비싸다.
참고 블로그 : https://cpm0722.github.io/operating-system/concurrency
'CS' 카테고리의 다른 글
| PE 포맷 구조 분석과 실행파일 조작하는 방법 (2) | 2025.07.30 |
|---|---|
| Floating Point 란? (2) | 2025.07.21 |
| 쓰레드와 컨텍스트 스위칭 (1) | 2024.09.18 |
| Stack Frame과 함수 호출 규약(__stdcall) (1) | 2024.04.28 |
| [CS] 가상 메모리와 페이징 (1) | 2023.08.15 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!