Linux 並無原生「線程」概念,僅有任務。所謂線程,是通過 clone() 系統調用以不同標誌位創建的共享資源的任務。本文從地址空間、資源共享、調度實體、創建參數、同步開銷五個維度,徹底釐清內核線程、輕量級進程(LWP)、用戶線程、普通進程的本質差異。
| 維度 | 普通進程 | 輕量級進程 (LWP) | 內核線程 | 用戶線程 |
|---|---|---|---|---|
| 地址空間 | 獨立 mm_struct | 共享父進程 mm_struct (CLONE_VM) | 無用戶空間 (mm=NULL) | 所屬進程共享 |
| task_struct | 獨立 | 獨立 | 獨立 | 無(用戶庫管理) |
| 調度實體 | 是 | 是(與內核線程 1:1) | 是 | 否(用戶態調度) |
| 創建方式 | fork() / clone() | clone(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND...) | kthread_create() | pthread_create (NPTL) 等用戶庫 |
| 特權級 | 用戶態/核心態切換 | 用戶態/核心態切換 | 僅核心態 | 用戶態 |
| 同步開銷 | 高(需核心協助) | 中(共享內存+futex) | 低(核心內部鎖) | 極低(用戶態自旋/鎖) |
| 上下文切換 | 完整切換(CR3、TSS 等) | 輕量(共享頁表、打開文件) | 極輕(無用戶態上下文) | 用戶態極快(無核心介入) |
kthread_create()/kernel_thread() 創建,mm = NULL。ksoftirqd、kworker、migration、rcu_gp、kswapd、jbd2 等。clone(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM ...)。task_struct、棧、寄存器、thread_info、pid(對外可見為線程 ID,內核內部為 task PID)、tid、tgid(線程組 ID,即進程 PID)。getpid() 返回 tgid,gettid() 返回 pid。getpid() 返回線程 ID。CLONE_THREAD 標誌創建線程組,共享 signal_struct、sighand_struct,完美符合 POSIX。| 場景 | 推薦模型 | 理由 |
|---|---|---|
| CPU 密集、需多核並行 | LWP (pthread) | 利用多核、核心調度公平 |
| IO 密集、超高併發(百萬連接) | 用戶線程/協程 + epoll | 單線程事件循環,避免線程切換開銷 |
| 核心後台服務、中斷處理 | 內核線程 | 無用戶態上下文,響應最快 |
| 隔離安全、獨立資源 | 普通進程 | 地址空間隔離、崩潰不波及 |
Linux 以 task_struct 統一描述所有調度實體:
普通進程 = 獨立資源 + 獨立調度;
LWP = 共享資源(mm/files/fs/signal)+ 獨立調度;
內核線程 = 無用戶資源 + 獨立調度;
用戶線程 = 用戶態自管調度,核心不可見。
理解「共享什麼、調度由誰負責、阻塞影響範圍」,即可在高併發架構中做出正確抉擇。