首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 線程創建記憶體細節:pthread_create、獨立堆疊與共享地址空間

     編輯:關於C語言

Linux 線程創建記憶體細節:pthread_create 與共享地址空間

線程是進程內的輕量級執行單元。pthread_create() 創建線程時,記憶體佈局與進程 fork() 截然不同:共享代碼/資料/堆,僅私有堆疊。

核心記憶體分區共享規則

pthread_create 簽名與記憶體參數

int pthread_create(pthread_t *thread,
                   const pthread_attr_t *attr,
                   void *(*start_routine)(void *),
                   void *arg);
  • attr:屬性物件,可設定 堆疊大小/位址 (pthread_attr_setstack)、分離狀態、調度策略
  • start_routine:線程入口函數,獨立執行流
  • 返回 0 成功,錯誤碼參見 man pthread_create

底層實現:clone() 系統呼叫

int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...);

pthread_create 封裝 clone(),關鍵 flags:

記憶體區域線程共享說明
代碼段是所有線程執行同一程式碼
資料段 (全域/靜態變數)是需同步機制保護
堆是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 匿名映射)。

線程 vs 進程記憶體對比

特性進程 (fork)線程 (pthread_create)
創建開銷較大 (複製頁表、COW 設置)極小 (僅分配堆疊、TCB)
切換開銷大 (TLB 刷新、頁表切換)小 (共享頁表、僅寄存器/堆疊指標)
通訊方式IPC (管道、Socket、共享記憶體)直接讀寫全域變數 (需同步)
隔離性完全隔離,崩潰不影響其他共享地址空間,一線程崩潰 = 進程崩潰
資源限制受 RLIMIT_NPROC 限制受 RLIMIT_NPROC + 記憶體限制 (堆疊×數量)

實務陷阱與最佳實踐

  1. 堆疊溢出:遞迴深、大區域變數 → 調大 pthread_attr_setstacksize 或改用動態分配
  2. 資料競爭:共享變數必須用 mutex/RWlock/atomic 保護
  3. 線程安全函數:優先用 _r 後綴版本 (localtime_r, strtok_r),避免靜態緩衝區衝突
  4. TLS 使用:__thread int tls_var; (GCC) 或 pthread_key_create 跨平台
  5. 取消點:長時間阻塞操作 (pthread_testcancel) 確保可響應取消
  6. 分離 vs 連接: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 位址不同 (獨立堆疊)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved