90. 프로세스 제어 블록 (PCB, Process Control Block) / 태스크 제어 블록 (TCB)

핵심 인사이트 (3줄 요약)

  1. 본질: PCB (Process Control Block)는 운영체제가 실행 중인 프로세스를 관리하기 위해 고유 번호(PID), 상태, 레지스터 값 등 모든 메타데이터를 저장하는 커널 공간의 핵심 자료구조이다.
  2. 가치: CPU (Central Processing Unit) 시분할 스케줄링 시, 이전 작업 상태를 완벽히 저장하고 복원하는 문맥 교환 (Context Switch)의 물리적 바탕이 되어 멀티태스킹을 가능하게 한다.
  3. 융합: 멀티스레딩의 발전으로 단일 프로세스 아래 여러 스레드가 생겨나면서, 공유 자원은 PCB에 두고 스레드별 고유 상태는 TCB (Task Control Block)에 분리 저장하는 계층적 구조로 진화했다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 프로세스 제어 블록 (PCB, Process Control Block)은 커널이 시스템 내의 각 프로세스를 추적, 제어하기 위해 유지하는 구조체 레코드다. 리눅스에서는 task_struct라는 이름으로 불리며, 프로세스의 '주민등록증'이자 '생명유지 장치' 역할을 한다. TCB (Task/Thread Control Block)는 스레드 단위의 스케줄링과 상태 정보를 담는 구조체로, 통상 PCB 내부에 종속되거나 연결되어 있다.
  • 필요성: 하나의 CPU 코어는 한 번에 하나의 명령어 흐름만 실행할 수 있다. 운영체제가 프로세스 A를 잠시 멈추고 B를 실행했다가 다시 A로 돌아오려면, A가 멈추던 순간에 CPU 레지스터에 어떤 값이 있었고 메모리의 어디를 실행 중이었는지를 완벽하게 기억해야 한다. 이 '기억'을 담는 안전한 금고가 바로 PCB다. PCB가 없다면 중단된 작업을 이어서 수행하는 것은 불가능하다.
  • 💡 비유: PCB는 "독서광이 두꺼운 책을 읽다 잠시 덮을 때 꽂아두는 상세한 책갈피와 메모장"과 같다. 몇 페이지 몇 번째 줄을 읽고 있었는지(Program Counter), 등장인물의 관계가 어떻게 되는지(Registers, Memory) 다 적혀있어서, 며칠 뒤에 책을 다시 펼쳐도 즉시 몰입할 수 있게 해준다.
  • 등장 배경: 과거 일괄 처리(Batch) 시스템에서는 한 작업이 끝나면 다음 작업이 시작되므로 상태 보존이 필요 없었다. 그러나 시분할 (Time-Sharing) 및 인터럽트 기반 시스템이 등장하면서 수시로 CPU 주인이 바뀌게 되었고, 하드웨어 문맥(Context)을 커널 메모리에 백업해두기 위한 전용 자료구조인 PCB가 탄생했다.

프로세스의 실행과 문맥 교환(Context Switch) 사이에서 PCB가 어떻게 백업소 역할을 하는지를 보여주는 흐름도다. 상태 저장과 복원이 교차하는 타이밍이 핵심이다.

  ┌──────────────────────────────────────────────────────────────────────────┐
  │                 문맥 교환 시 PCB의 역할 (Context Switch)                 │
  ├──────────────────────────────────────────────────────────────────────────┤
  │                                                                          │
  │  [Process A]                [OS Kernel]              [Process B]         │
  │      │                          │                         │              │
  │      ▼       인터럽트/시스템 콜 발생│                         │          │
  │  (실행 중) ────────────────────▶│                         │              │
  │      │                   ┌──────▼──────┐                  │              │
  │      │                   │ A 상태를 PCB_A에│                  │          │
  │      │                   │ 저장 (Save)    │                  │           │
  │      │                   └──────┬──────┘                  │              │
  │      │                   ┌──────▼──────┐                  │              │
  │      │                   │ B 상태를 PCB_B서│                  │          │
  │      │                   │ 복원 (Restore)  │                  │          │
  │      │                   └──────┬──────┘                  │              │
  │      │                          │◀──────────────────── (실행 재개)       │
  │      │                          │                         ▼              │
  │                                                                          │
  │  해설: 저장 및 복원 구간 동안 CPU는 유저 프로세스 대신 커널 코드만 실행함│
  └──────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 이 흐름도의 핵심은 Process A에서 Process B로 제어권이 넘어갈 때 중간에 OS 커널이 개입하는 "오버헤드 윈도우"를 보여준다는 점이다. 프로세스 A가 할당된 시간을 다 쓰거나 입출력을 요청하면 인터럽트가 발생하고 커널 모드로 진입한다. 커널은 CPU 레지스터의 현재 값(A의 문맥)을 모두 PCB_A 구조체에 덮어쓴다(Save). 그런 다음 스케줄러가 B를 선택하면, 보관되어 있던 PCB_B에서 레지스터 값을 읽어와 CPU에 덮어쓴다(Restore). 이 저장과 복원 시간 동안 유저의 실제 애플리케이션 코드는 1바이트도 실행되지 않으므로, 이 구간이 짧을수록 시스템 성능이 높아진다.

  • 📢 섹션 요약 비유: 게임을 끄기 전에 '세이브 파일(PCB)'을 만들고, 다음 날 다시 게임을 켤 때 '로드(Restore)'를 해야만 어제 잡다 만 몬스터부터 다시 싸울 수 있는 원리와 동일합니다.

Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

구성 요소 (PCB 내부 구조 개괄)

요소명역할내부 동작포함 데이터비유
프로세스 식별자 (PID)시스템 내 프로세스 고유 구분커널 해시 테이블에서 검색 키로 사용PID, PPID, UID주민등록번호
프로세스 상태 (State)현재 프로세스의 스케줄링 상태Ready, Running, Wait, Zombie 등상태 열거형 값현재 활동 상태 (대기/식사)
CPU 레지스터 문맥중단 시점의 하드웨어 상태 보존스위칭 시 CPU 레지스터 값을 복사PC, SP, 범용 레지스터책갈피 꽂은 정확한 줄 번호
메모리 관리 정보주소 공간 고립 및 물리 메모리 매핑MMU (Memory Management Unit) 갱신 시 사용페이지 테이블 포인터개인 전용 방의 지도
스케줄링 & I/O 정보자원 할당과 통제 데이터스케줄러가 큐 정렬 시 참고우선순위, 열린 파일 목록VIP 등급과 빌린 물건 목록

PCB 공간 레이아웃 및 커널 위치

PCB는 유저가 임의로 조작할 수 없도록 반드시 보안이 보장된 커널 메모리 (Kernel Space) 공간 내에만 존재한다.

  ┌─────────────────────────────────────────────────────────────────────────┐
  │                 메모리 공간 내 프로세스와 PCB의 분리 배치               │
  ├─────────────────────────────────────────────────────────────────────────┤
  │                                                                         │
  │  [ User Space ]                    [ Kernel Space ]                     │
  │                                                                         │
  │  ┌────────────┐                    ┌─────────────────────┐              │
  │  │ Code / Text│◀───────┐           │ PCB 배열 / 리스트     │            │
  │  ├────────────┤        │           │ ┌─────────────────┐ │              │
  │  │ Data / BSS │        │포인터 매핑   │ │ PCB_1 (PID 10)  │ │           │
  │  ├────────────┤        └───────────┼─│ PC, SP, Page Tb │ │              │
  │  │ Heap ──▶   │                    │ └─────────────────┘ │              │
  │  │            │                    │ ┌─────────────────┐ │              │
  │  │ ◀── Stack  │                    │ │ PCB_2 (PID 12)  │ │              │
  │  └────────────┘                    │ └─────────────────┘ │              │
  │                                    └─────────────────────┘              │
  │  결론: 악성 프로세스가 자신의 권한이나 상태를 변조할 수 없도록 격리됨   │
  └─────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 이 구조도는 시스템의 보안성과 안정성의 근간을 보여준다. 유저 공간(User Space)에는 애플리케이션의 코드, 데이터, 힙, 스택이 존재하지만, 정작 이 프로세스를 통제하는 메타데이터인 PCB는 유저 공간에 없다. 커널 공간(Kernel Space)에만 존재한다. 만약 PCB가 유저 공간에 있다면, 악성 해커나 버그가 발생한 코드가 자신의 PCB에 접근하여 UID를 0(Root)으로 바꾸거나 락 상태를 임의로 조작해 시스템 전체를 파괴할 수 있다. 이 철저한 격리 덕분에 PCB 내용은 오직 시스템 콜 (System Call)을 통해서만 커널에 의해 안전하게 조작될 수 있다.

PCB와 TCB의 계층적 연동 (Hierarchical Structure)

현대 멀티스레드 환경에서는 "실행의 기본 단위"가 스레드로 바뀌었다. 이에 따라 기존 PCB의 역할 중 공유 가능한 자원은 PCB에 남겨두고, 스레드별로 다르게 관리해야 하는 CPU 문맥 등은 TCB (Task Control Block)로 쪼개어 관리하는 계층 구조를 갖는다.

  ┌────────────────────────────────────────────────────────────────────────┐
  │               멀티스레드 환경에서의 PCB와 TCB 관계 계층도              │
  ├────────────────────────────────────────────────────────────────────────┤
  │                                                                        │
  │  [ Process Control Block (PCB) ]                                       │
  │  │ PID: 1024, 주소 공간(Page Table), 열린 파일(FD) 등 자원 공유│       │
  │  └─┬──────────────┬───────────────┬───────────────────────┘            │
  │    │              │               │                                    │
  │    ▼              ▼               ▼                                    │
  │ [ TCB 1 ]      [ TCB 2 ]       [ TCB 3 ]                               │
  │ │TID: 1  │     │TID: 2  │      │TID: 3  │                              │
  │ │PC, SP  │     │PC, SP  │      │PC, SP  │                              │
  │ │Register│     │Register│      │Register│                              │
  │ └────────┘     └────────┘      └────────┘                              │
  │                                                                        │
  │ 결론: 스레드 전환(TCB 교체)은 PCB 교체보다 훨씬 비용이 적고 빠름       │
  └────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 이 도식은 멀티스레딩이 왜 가벼운지(Lightweight) 증명한다. 상단의 PCB는 프로세스 전체의 공유 자원인 메모리 매핑 정보(페이지 테이블)와 열린 파일 목록 등을 보유한다. 하단의 TCB들은 각 스레드의 실행 흐름만을 추적하기 위해 고유의 프로그램 카운터(PC), 스택 포인터(SP), CPU 레지스터 값만을 보관한다. 만약 같은 프로세스 내의 TCB 1에서 TCB 2로 문맥 교환이 일어나면, 메모리 매핑은 그대로 두고 레지스터 값만 바꾸면 되므로 TLB (Translation Lookaside Buffer) 플러시가 발생하지 않는다. 이것이 스레드 간 문맥 교환이 프로세스 간 교환보다 압도적으로 빠른 핵심 구조적 이유다.

  • 📢 섹션 요약 비유: PCB가 한 가족의 '가족관계증명서와 집 문서'라면, TCB는 그 집에 사는 각 가족 구성원들의 '개인 다이어리와 방 열쇠'와 같이 역할이 분리되어 있습니다.

Ⅲ. 융합 비교 및 다각도 분석

심층 기술 비교: PCB 기반 문맥 교환 vs TCB 기반 문맥 교환

비교 항목프로세스 교환 (Process Context Switch)스레드 교환 (Thread Context Switch)판단 포인트
교체 대상PCB 전체 및 TCB같은 PCB 내의 TCB 간 교체오버헤드 규모
메모리 맵 교체CR3 레지스터 변경 (페이지 테이블 교체)불필요 (동일한 주소 공간 공유)하드웨어 비용
캐시 영향TLB 플러시 발생, 캐시 미스 극심TLB 유지, L1/L2 캐시 히트 확률 높음성능 저하 여부
커널 개입반드시 개입 (무거운 작업)커널 스레드는 개입, 유저 스레드는 불필요스케줄링 지연

과목 융합 관점

  • 보안 (Security): 커널 취약점 공격(Exploit) 중 상당수가 커널 메모리에 위치한 task_struct의 주소를 알아내어 구조체 내의 cred(권한) 포인터를 조작하는 방식이다. 이를 막기 위해 KASLR (Kernel Address Space Layout Randomization) 기법이 PCB의 메모리 위치를 부팅 시마다 난수화한다.

  • 클라우드 및 컨테이너 (Cloud / Container): 도커(Docker) 같은 컨테이너 기술은 근본적으로 호스트 OS의 단일 커널 위에서 동작한다. 따라서 컨테이너 안의 프로세스들도 모두 호스트 OS의 커널 공간에 PCB로 등록되지만, 네임스페이스 (Namespace) 메타데이터를 PCB에 추가하여 서로 격리된 것처럼 환상을 제공한다.

  • 📢 섹션 요약 비유: 이사를 갈 때 아예 다른 동네로 짐을 다 싸서 가는 것(PCB 교체)과, 같은 집 안에서 거실에서 안방으로 자리만 옮기는 것(TCB 교체)만큼이나 비용과 시간이 다르게 소모됩니다.


Ⅳ. 실무 적용 및 기술사적 판단

실무 시나리오 및 판단

  1. 시나리오 — 프로세스 폭탄 (Fork Bomb) 공격 방어: 시스템에 악의적인 스크립트가 무한 루프로 fork() 시스템 콜을 호출하여 초당 수만 개의 자식 프로세스를 생성.
    • 판단: 커널 메모리는 유한하다. 각 PCB(task_struct)가 차지하는 약 8KB의 커널 스택 공간이 고갈되어 시스템 패닉(OOM, Out Of Memory)이 발생한다. 실무 엔지니어는 ulimit -u (최대 사용자 프로세스 수) 설정을 제한하거나 커널 파라미터 kernel.pid_max를 적절히 조절하여 PCB 무한 생성 공격을 원천 차단해야 한다.
  2. 시나리오 — 좀비 프로세스 (Zombie Process) 적체로 인한 PID 고갈: top 명령어로 확인 시 'Z' 상태의 프로세스가 수백 개 쌓여 있고, 새 프로세스 실행 시 "Cannot allocate memory" 에러가 발생.
    • 판단: 좀비 상태는 프로세스가 종료되어 메모리 등 자원은 반납했으나, 부모 프로세스가 wait()를 호출하지 않아 커널이 '종료 상태(Exit Status)'를 전달하기 위해 아주 작은 PCB 뼈대만을 남겨둔 상태다. 부모 프로세스의 코드를 수정하여 제대로 회수(Reaping)하게 하거나, 부모를 강제 종료하여 고아(Orphan)로 만든 뒤 init(PID 1)이 회수하도록 처리해야 한다.

실무에서 프로세스 라이프사이클 중 나타나는 비정상 상태(좀비)와 PCB의 잔류 구조를 이해하기 위한 트리 도식이다.

  ┌───────────────────────────────────────────────────────────────────────────┐
  │                 좀비 프로세스 발생과 PCB 잔류 메커니즘                    │
  ├───────────────────────────────────────────────────────────────────────────┤
  │                                                                           │
  │    [Parent Process]                          [Child Process]              │
  │           │           1. fork()                     │                     │
  │           ├────────────────────────────────────────▶│                     │
  │           │           2. 실행 완료 및 exit()          │                   │
  │     바쁜 작업 중 ◀───────────────────────────────────┤                    │
  │  (wait 미호출!)       3. SIGCHLD 신호 대기             │                  │
  │           │                                         ▼                     │
  │           │                              [Zombie State 🧟]                │
  │           │                            - 유저 메모리는 모두 해제됨        │
  │           │                            - 커널에 PCB만 덩그러니 남음       │
  │           │                            - PID를 반납하지 못함              │
  │                                                                           │
  │ 실무 교훈: 부모가 자식의 죽음을 확인(wait)해줘야 커널이 PCB를 최종 삭제함 │
  └───────────────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 이 그림은 실무에서 가장 흔하게 마주하는 PID 고갈 장애의 원인을 명확히 짚어준다. 자식 프로세스는 exit()을 통해 자신이 사용하던 메모리와 열린 파일 등 무거운 자원을 모두 OS에 반납한다. 하지만 자신의 종료 코드(Exit Status)를 부모에게 알려야 하는 임무 때문에, 자기 자신의 신분증인 PCB(Task Struct의 일부분)와 PID 번호는 커널에 남겨둔다. 부모가 바쁘거나 버그로 인해 wait() 시스템 콜을 호출해 주지 않으면 이 상태가 무한정 지속되며 이를 좀비라고 부른다. 좀비 자체는 RAM을 많이 먹지 않지만, OS가 발급 가능한 PID 풀(Max 32768 등)을 잠식하여 시스템을 서서히 마비시킨다.

도입 체크리스트 및 안티패턴

  • 운영적 체크리스트: 컨테이너 환경을 설계할 때, 호스트 기반의 PIDs Cgroup 리미트가 걸려 있어 노드 전체의 PID가 고갈되지 않도록 안전장치를 마련했는가?

  • 안티패턴: 멀티스레드 앱에서 스레드를 종료할 때 자원을 제대로 정리하지 않고(Detached 안 함) 방치하여 TCB가 누수(Leak)되는 현상. JVM이나 Go 런타임 외의 C/C++ 네이티브 환경에서 매우 치명적이다.

  • 📢 섹션 요약 비유: 직원이 퇴사(exit)할 때 쓰던 비품은 다 반납했지만, 인사팀(부모)이 퇴사 처리를 결재(wait)해주지 않아서 전산상 직원 명부(PCB)에 이름이 남아 신규 채용(PID 할당)을 막는 답답한 상황입니다.


Ⅴ. 기대효과 및 결론

정량/정성 기대효과

구분모놀리식 프로세스 기반 구조스레드(TCB) 분리 및 최적화개선 효과
정량교환 시 TLB 미스 및 메모리 복사공유 자원 유지, TCB만 교환문맥 교환 지연시간 수십 배 단축
정성상태 관리 복잡, 보안 취약커널 공간 내 구조적 격리악의적 메모리 변조 원천 차단
정성자원 해제 지연으로 좀비 발생Cgroups를 통한 자원 한도 통제시스템 마비 및 PID 고갈 방지

미래 전망 및 표준

  • eBPF를 통한 가시성 확보: 과거에는 커널 내의 task_struct(PCB) 필드 변화를 모니터링하기 위해 커널 모듈을 직접 짜야 했으나, 이제는 BPF(Berkeley Packet Filter)를 이용해 시스템 중단 없이 안전하게 PCB의 상태 변화, I/O 대기 시간, 스케줄링 지연을 실시간 추적하는 도구(Cilium 등)가 표준으로 자리잡았다.

  • 경량 스레드 (Goroutine / Virtual Thread): 사용자 공간에서 수백만 개의 초경량 가상 TCB를 유저 런타임이 직접 관리하고, 커널 PCB 하나에 다수를 맵핑(N:M 스케줄링)하여 커널 개입 비용을 아예 0으로 만드는 아키텍처가 최신 백엔드 언어의 대세가 되었다.

  • 📢 섹션 요약 비유: 무거운 종이 서류철(초기 PCB)에서 시작해, 이제는 스마트폰 앱 안에서 수만 개의 일정(가상 스레드 TCB)을 렉 없이 동시에 관리하는 클라우드 동기화 시스템으로 발전한 것입니다.


📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
문맥 교환 (Context Switch)이전 프로세스의 상태를 PCB에 덮어쓰고 새 프로세스의 PCB를 레지스터로 올리는 일련의 과정이다.
TLB (Translation Lookaside Buffer)문맥 교환 시 프로세스 주소 공간이 바뀌면(PCB 내 페이지 테이블 교체) 플러시 되어야 하므로 성능 하락의 주원인이다.
좀비 프로세스 (Zombie Process)유저 자원은 반납했으나 부모가 회수하지 않아 커널에 PCB와 PID만 덩그러니 남은 상태다.
Cgroups (Control Groups)리눅스에서 다수의 PCB를 그룹으로 묶어 CPU, 메모리 자원 할당량을 컨테이너 단위로 통제하는 기술이다.
유저 모드 / 커널 모드보안을 위해 유저 애플리케이션 코드는 PCB에 직접 접근할 수 없으며, 반드시 시스템 콜을 통해 모드 전환 후 커널이 대리 수행해야 한다.

👶 어린이를 위한 3줄 비유 설명

  1. PCB는 컴퓨터 안의 여러 프로그램(프로세스)들이 각자 자기가 누군지, 어디까지 일했는지, 어떤 물건을 빌렸는지 꼼꼼히 적어둔 비밀 일기장이에요.
  2. 이 일기장은 너무 중요해서 아무나 볼 수 없는 '커널 공간'이라는 튼튼한 금고 안에만 안전하게 보관되어 있어요.
  3. 컴퓨터가 한 게임을 하다가 유튜브를 볼 때, 게임의 일기장에 지금 상황을 쓱 적어두고 유튜브의 일기장을 꺼내오기 때문에 화면을 다시 켜도 방금 전 상황이 그대로 이어지는 거랍니다!