clone 시스템 콜 (clone System Call)

Ⅰ. 개요

1. 정의

clone 시스템 콜은 리눅스에서 프로세스와 스레드 생성을 모두 수행하는 통합 API이다. fork()pthread_create()의 기반이 되는 저수준 시스템 콜로, 플래그 설정을 통해 부모와 자식 간의 자원 공유 수준을 세밀하게 제어할 수 있다.

clone의 위치와 역할
┌─────────────────────────────────────────────────┐
│              사용자 수준 API                      │
│  ┌──────────┐  ┌────────────────────┐          │
│  │  fork()  │  │ pthread_create()   │          │
│  └────┬─────┘  └─────────┬──────────┘          │
│       │                  │                      │
│       ▼                  ▼                      │
│  ┌──────────────────────────────────┐           │
│  │         clone() 시스템 콜        │           │
│  │   (리눅스 유일 생성 인터페이스)   │           │
│  └──────────────────────────────────┘           │
│              커널 수준                           │
└─────────────────────────────────────────────────┘

비유: clone은 "부모의 물건 중 어떤 것을 공유하고 어떤 것을 새로 만들지 선택할 수 있는 이사 계약서"와 같다. fork는 "물건을 모두 복사해서 새 집으로 이사"하고, pthread_create는 "물건을 모두 공유하면서 같은 집에서 함께 사는 것"이다.

Ⅱ. clone 시스템 콜 인터페이스

1. 함수 원형

long clone(unsigned long flags, void *child_stack,
           int *ptid, int *ctid,
           unsigned long newtls);
매개변수설명
flags공유/복제 동작 제어 플래그
child_stack자식이 사용할 새 스택 포인터
ptid부모 스레드 ID 저장 위치
ctid자식 스레드 ID 저장 위치 (CLONE_CHILD_SETTID)
newtls새 TLS (Thread Local Storage) 주소

2. 주요 CLONE_* 플래그

clone 플래그와 자원 공유 범위
┌──────────────┬────────────────────────────────────┐
│   플래그      │         공유하는 자원               │
├──────────────┼────────────────────────────────────┤
│ CLONE_VM     │ 메모리 공간 (Address Space)         │
│ CLONE_FS     │ 파일 시스템 정보 (root, cwd, umask) │
│ CLONE_FILES  │ 파일 디스크립터 테이블               │
│ CLONE_SIGHAND│ 시그널 핸들러                        │
│ CLONE_THREAD │ 스레드 그룹 (동일 TGID)              │
│ CLONE_PARENT │ 부모와 같은 부모를 가짐              │
│ CLONE_PTRACE │ 디버거 추적 공유                     │
│ CLONE_SETTLS │ 새 TLS 영역 설정                     │
└──────────────┴────────────────────────────────────┘

Ⅲ. fork()와 pthread_create()의 clone 매핑

1. fork() = clone(최소 공유)

fork()의 clone 호출 (실제 구현 개념)
┌─────────────────────────────────────────────────┐
│                                                 │
│  fork() ≈ clone(SIGCHLD, child_stack)            │
│                                                 │
│  결과:                                          │
│  ┌─────────┐          ┌─────────┐              │
│  │ 부모    │          │ 자식    │               │
│  │ 메모리  │ ─ 복사 ─→│ 메모리  │  (CLONE_VM X)│
│  │ 파일테이블│─ 복사 ─→│ 파일테이블│ (CLONE_FILES X)│
│  │ 스택    │ ─ 복사 ─→│ 스택    │               │
│  │ 시그널  │ ─ 복사 ─→│ 시그널  │  (CLONE_SIGHAND X)│
│  └─────────┘          └─────────┘              │
│                                                 │
│  ★ 거의 모든 것이 독립적인 사본                 │
└─────────────────────────────────────────────────┘

2. pthread_create() = clone(모든 공유)

pthread_create()의 clone 호출 (실제 구현 개념)
┌─────────────────────────────────────────────────┐
│                                                 │
│  pthread_create() ≈ clone(                      │
│    CLONE_VM | CLONE_FS | CLONE_FILES |          │
│    CLONE_SIGHAND | CLONE_THREAD |               │
│    CLONE_SETTLS | CLONE_PARENT_SETTID |         │
│    CLONE_CHILD_CLEARTID, child_stack)           │
│                                                 │
│  결과:                                          │
│  ┌─────────┐          ┌─────────┐              │
│  │ 스레드 A│          │ 스레드 B│               │
│  │ 메모리  │ ─ 공유 ─→│ 메모리  │  (CLONE_VM O)│
│  │ 파일테이블│─ 공유 ─→│ 파일테이블│ (CLONE_FILES O)│
│  │ 시그널  │ ─ 공유 ─→│ 시그널  │  (CLONE_SIGHAND O)│
│  │ 스택    │  독립     │ 스택    │  (각자의 스택)│
│  └─────────┘          └─────────┘              │
│                                                 │
│  ★ 메모리/파일/시그널 공유, 스택만 독립         │
└─────────────────────────────────────────────────┘

3. fork() vs clone() vs pthread_create() 비교

자원 공유 비교표
┌────────────────┬─────────┬──────────────┬──────────────┐
│     자원       │ fork()  │   clone()    │pthread_create│
├────────────────┼─────────┼──────────────┼──────────────┤
│ 메모리 공간    │  복사   │ 플래그로 결정 │    공유      │
│ 파일 디스크립터│  복사   │ 플래그로 결정 │    공유      │
│ 파일시스템정보 │  복사   │ 플래그로 결정 │    공유      │
│ 시그널 핸들러  │  복사   │ 플래그로 결정 │    공유      │
│ 스택           │  복사   │  새 스택 필수 │  새 스택 필수 │
│ PID            │  새 PID │    새 PID     │  새 TID      │
│ 유연성         │   낮음  │    최고       │    중간      │
└────────────────┴─────────┴──────────────┴──────────────┘

Ⅳ. CLONE_* 플래그 상세

1. CLONE_VM (Virtual Memory)

CLONE_VM의 메모리 공유
┌─────────────────────────────────────────────────┐
│  CLONE_VM 설정 시 (스레드 생성):                │
│                                                 │
│  부모 task_struct ──┐                           │
│                     ├──→ mm_struct (공유)        │
│  자식 task_struct ──┘                           │
│                                                 │
│  CLONE_VM 미설정 시 (fork):                     │
│                                                 │
│  부모 task_struct ──→ mm_struct A               │
│  자식 task_struct ──→ mm_struct B (사본)        │
└─────────────────────────────────────────────────┘

2. CLONE_FS / CLONE_FILES / CLONE_SIGHAND

  • CLONE_FS: root 디렉토리, 작업 디렉토리, umask를 공유
  • CLONE_FILES: 열린 파일 디스크립터 테이블을 공유
  • CLONE_SIGHAND: 시그널 디스포지션(핸들러)과 보류/차단 시그널을 공유

3. CLONE_THREAD

CLONE_THREAD와 스레드 그룹
┌─────────────────────────────────────────────────┐
│                                                 │
│  CLONE_THREAD 설정 시:                          │
│  ┌──────────────────────────────────┐           │
│  │      스레드 그룹 (TGID: 1000)    │           │
│  │                                  │           │
│  │  TID 1000 ←─ 리더 스레드         │           │
│  │  TID 1001 ←─ CLONE_THREAD 생성  │           │
│  │  TID 1002 ←─ CLONE_THREAD 생성  │           │
│  │                                  │           │
│  │  ★ 모두 동일 TGID = 1000         │           │
│  │  ★ getpgrp(), getppid() 공유     │           │
│  │  ★ 하나가 exit() 시 전체 종료     │           │
│  └──────────────────────────────────┘           │
└─────────────────────────────────────────────────┘

Ⅴ. 지식 그래프 및 요약

1. 지식 그래프

[clone 시스템 콜]
├── [상위 API]
│   ├── fork() ─── SIGCHLD만 설정 (최소 공유)
│   ├── vfork() ── CLONE_VFORK | CLONE_VM (메모리 완전 공유)
│   └── pthread_create() ── 모든 CLONE_* 플래그 설정
├── [공유 제어 플래그]
│   ├── CLONE_VM ────── 메모리 공간
│   ├── CLONE_FS ────── 파일시스템 정보
│   ├── CLONE_FILES ─── 파일 디스크립터
│   ├── CLONE_SIGHAND ── 시그널 핸들러
│   └── CLONE_THREAD ── 스레드 그룹 (TGID)
├── [독립 자원]
│   ├── PID/TID
│   ├── 스택 (항상 새로 할당)
│   └── 레지스터 상태
└── [특수 변형]
    ├── CLONE_UNTRACED ─── 추적 방지
    └── CLONE_NEWNS ────── 새 마운트 네임스페이스

2. 준말

  • TLS: Thread Local Storage (스레드 로컬 저장소)
  • TGID: Thread Group ID (스레드 그룹 식별자)
  • TID: Thread ID (스레드 식별자)

3. 어린이를 위한 3줄 설명

clone은 새로운 프로세스나 스레드를 만들 때 "부모의 것 중 어떤 것을 같이 쓰고 어떤 것을 새로 만들지" 선택할 수 있는 마법의 복사기예요. fork는 "모든 물건을 똑같이 복사해서 새 집에 사는 것"이고, 스레드는 "방만 따로 쓰고 나머지는 다 같이 쓰는 것"이에요. 이 하나의 명령어로 리눅스의 프로세스와 스레드를 모두 만들어낼 수 있어요.