線程是進程內的輕量級執行單元。pthread_create() 創建線程時,記憶體佈局與進程 fork() 截然不同:共享代碼/資料/堆,僅私有堆疊。
| 記憶體區域 | 線程共享 | 說明 |
|---|---|---|
| 代碼段 | 是 | 所有線程執行同一程式碼 |
| 資料段 (全域/靜態變數) | 是 | 需同步機制保護 |
| 堆 | 是 | malloc/free 線程安全,但應用層資料競爭需鎖 |
| 堆疊 | 否 | 每線程獨立,默認 8MB (可調) |
| 線程局部儲存 (TLS) | 否 | __thread / pthread_key_create |
| Flag | 含義 | 線程/進程 |
|---|---|---|
CLONE_VM | 共享記憶體空間 | 線程 |
CLONE_FS | 共享檔案系統資訊 | 線程 |
CLONE_FILES | 共享檔案描述符表 | 線程 |
CLONE_SIGHAND | 共享信號處理器 | 線程 |
CLONE_THREAD | 放入同一線程組 (共享 PID) | 線程 |
CLONE_CHILD_SETTID | 設定子線程 TID | 線程 |
child_stack:指向子線程堆疊頂端 (高地址),由 pthread_create 分配 (通常 mmap 匿名映射)。
| 特性 | 進程 (fork) | 線程 (pthread_create) |
|---|---|---|
| 創建開銷 | 較大 (複製頁表、COW 設置) | 極小 (僅分配堆疊、TCB) |
| 切換開銷 | 大 (TLB 刷新、頁表切換) | 小 (共享頁表、僅寄存器/堆疊指標) |
| 通訊方式 | IPC (管道、Socket、共享記憶體) | 直接讀寫全域變數 (需同步) |
| 隔離性 | 完全隔離,崩潰不影響其他 | 共享地址空間,一線程崩潰 = 進程崩潰 |
| 資源限制 | 受 RLIMIT_NPROC 限制 | 受 RLIMIT_NPROC + 記憶體限制 (堆疊×數量) |
pthread_attr_setstacksize 或改用動態分配_r 後綴版本 (localtime_r, strtok_r),避免靜態緩衝區衝突__thread int tls_var; (GCC) 或 pthread_key_create 跨平台pthread_testcancel) 確保可響應取消pthread_detach 自動回收資源,pthread_join 同步等待返回值#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int shared = 100;
__thread int tls = 200;
void *thread_func(void *arg) {
int local = 300;
printf("Thread: shared=%d (%p), tls=%d (%p), local=%d (%p)\n",
shared, &shared, tls, &tls, local, &local);
shared = 400; tls = 500; local = 600;
return NULL;
}
int main() {
pthread_t tid;
pthread_create(&tid, NULL, thread_func, NULL);
sleep(1);
printf("Main: shared=%d (%p), tls=%d (%p)\n", shared, &shared, tls, &tls);
pthread_join(tid, NULL);
return 0;
}
輸出顯示:shared 位址相同 (共享),tls 位址不同 (TLS),local 位址不同 (獨立堆疊)。