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

POSIX 執行緒基礎:建立、互斥鎖、同步與鎖效能對比

     編輯:關於C語言

前言

掌握 pthread_create、pthread_mutex、pthread_join 三大核心 API,即可編寫基本多執行緒程式。本文對比「無同步」、「互斥鎖同步」、「條件變數同步」三種模式,並說明鎖爭用對效能的影響。

一、基本建立與回收

pthread_t tid;
pthread_create(&tid, NULL, thread_func, arg); // 建立
pthread_join(tid, NULL);                      // 等待結束並回收資源
pthread_detach(tid);                          // 或分離,自動回收
  • 第四參數 void* arg 傳遞單一參數,複雜資料請打包成結構體
  • 執行緒函式簽名:void* func(void*)

二、範例 1:無同步(資料競爭)

int counter = 0;
void* inc(void*) {
    for (int k = 0; k < 100000; ++k) ++counter; // 非原子,結果不可預期
    return NULL;
}
// 兩條執行緒同時跑,counter 遠小於 200000

三、範例 2:互斥鎖保護

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;

void* inc_safe(void*) {
    for (int k = 0; k < 100000; ++k) {
        pthread_mutex_lock(&mtx);
        ++counter;
        pthread_mutex_unlock(&mtx);
    }
    return NULL;
}
// 正確但鎖爭用頻繁,效能下降

四、範例 3:條件變數協作(同上文)

參考上一篇「條件變數實戰」,實現「執行緒 A 每 3 次通知 B」。

五、效能觀察與優化方向

模式適用場景效能特徵
無同步唯讀共享、Thread-Local最快但不安全
粗粒度鎖簡單計數器、短臨界區鎖爭用高,擴展性差
細粒度鎖多資料結構獨立操作降低爭用,增加複雜度
無鎖/原子操作計數器、旗標、環形緩衝最佳擴展性,需記憶體順序知識
條件變數生產消費、狀態機等待休眠喚醒開銷,避免忙等待

六、C++17 標準庫對應

// 建立
std::thread t(func, args...);
t.join(); / t.detach();

// 互斥鎖
std::mutex mtx;
std::lock_guard lk(mtx); // RAII,自動解鎖

// 條件變數
std::condition_variable cv;
std::unique_lock ul(mtx);
cv.wait(ul, predicate);
cv.notify_one(); / notify_all();

七、除錯技巧

  • gdb:info threads、thread apply all bt 檢視所有執行緒堆疊
  • Helgrind/ThreadSanitizer:自動偵測資料競爭、死鎖
  • 日誌加入執行緒 ID:std::this_thread::get_id()

八、最佳實務清單

  1. 鎖的持有時間越短越好
  2. 永遠以固定順序獲取多把鎖,避免死鎖
  3. 優先使用 std::lock_guard/unique_lock 防止忘記解鎖
  4. 共享資料最小化,傾向 Thread-Local 或訊息傳遞
  5. 無鎖程式設計需深入理解 std::memory_order
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved