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

APUE 執行緒程式設計完整指南:建立、同步、互斥鎖、條件變數與令牌桶實戰

     編輯:關於C語言

Unix 環境高級編程(APUE)第 11-12 章:POSIX 執行緒深度實戰

執行緒是 CPU 排程基本單位,共享進程位址空間,建立/切換開銷遠小於進程。POSIX 執行緒 (pthread) 提供標準化跨平台介面,是高併發伺服器開發核心技術。

1. 基本操作 API

函數用途關鍵點
pthread_create建立執行緒需 -pthread 編譯連結,傳入啟動函數 void*(*)(void*)
pthread_join等待執行緒結束 (收屍)任意執行緒可 join 任意執行緒,無父子關係
pthread_exit主動結束執行緒返回值透過 join 的 void** 取得
pthread_cancel請求取消執行緒非立即生效,需到達取消點 (如 pthread_testcancel、I/O 系統呼叫)
pthread_detach分離執行緒資源自動回收,不可 join
pthread_self/pthread_equal取得/比較執行緒 ID不直接操作 pthread_t,不透明類型

2. 執行緒清理處理程序

pthread_cleanup_push(routine, arg); // 註冊
// ... 程式碼區塊 ...
pthread_cleanup_pop(execute);       // 執行並彈出 (execute=1) 或 僅彈出 (0)
  • 成對使用的宏,展開為 do { ... } while(0) 結構
  • 執行順序:後進先出 (LIFO),類似 atexit
  • 執行緒退出 (exit/cancel) 時自動執行所有已推入的清理函數

3. 互斥鎖 保護臨界區

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 靜態初始化
pthread_mutex_init(&mutex, NULL);                   // 動態初始化

pthread_mutex_lock(&mutex);   // 阻塞式加鎖
pthread_mutex_trylock(&mutex); // 非阻塞嘗試
pthread_mutex_unlock(&mutex);  // 解鎖
pthread_mutex_destroy(&mutex); // 銷毀 (釋放資源)

臨界區原則:加鎖→最小操作→解鎖。鎖保護的是程式碼區段,非變數本身。

4. 經典同步問題:有序列印 abcd

四執行緒循環列印 a/b/c/d,使用條件變數比鎖鏈更優雅:

pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int num = 0; // 當前應列印的執行緒編號 0-3

void* thr_func(void* arg) {
    int n = (int)arg; char ch = 'a' + n;
    while (1) {
        pthread_mutex_lock(&mut);
        while (num != n) pthread_cond_wait(&cond, &mut); // 原子解鎖+等待
        putchar(ch);
        num = (num + 1) % 4;
        pthread_cond_broadcast(&cond); // 喚醒所有等待者
        pthread_mutex_unlock(&mut);
    }
}

5. 條件變數 實現通知機制

函數語義
pthread_cond_wait原子:解鎖 mutex + 睡眠等待 + 重新加鎖
pthread_cond_timedwait帶超時的等待
pthread_cond_signal喚醒一個等待者
pthread_cond_broadcast驚群:喚醒所有等待者

選擇原則:明確知道誰該工作用 signal,不確定或多對多用 broadcast。

6. 實戰專案:通用多執行緒令牌桶庫

支援 1024 個獨立桶,每桶固定速率 (CPS) 與突發上限:

  • 全域陣列 job[MAX] + 全域鎖 mut_job 保護桶陣列
  • 每桶結構體含 cps, burst, token, pos, mut, cond
  • 專用執行緒 thr_alrm 每秒 sleep(1) 遍歷所有桶填充 token,pthread_cond_broadcast 通知等待者
  • mytbf_fetchtoken:while(token<=0) pthread_cond_wait(&cond, &mut); 非忙等待
  • pthread_once 確保填充執行緒只啟動一次
  • 模組卸載時 pthread_cancel + join 回收執行緒,銷毀所有鎖/條件變數

7. 進階主題

  • 執行緒上限:受 PID 耗盡與虛擬位址空間棧區大小限制 (ulimit -s 調整)
  • 管道特性:單工、FIFO、讀寫雙方必須湊齊否則阻塞
  • 訊號與執行緒混用:避免大範圍混用,訊號屬進程級,執行緒屬執行緒級,易產生競態
  • sched_yield:主動讓出 CPU,配合 trylock 避免死鎖

編譯執行提醒

gcc -Wall -pthread thread_demo.c -o thread_demo
ps ax -L  # 查看 LWP (執行緒 ID) 驗證建立成功

掌握 pthread 同步原語與設計模式,是構建高效能、高可靠性併發系統的關鍵能力。

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