掌握 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*)int counter = 0;
void* inc(void*) {
for (int k = 0; k < 100000; ++k) ++counter; // 非原子,結果不可預期
return NULL;
}
// 兩條執行緒同時跑,counter 遠小於 200000
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;
}
// 正確但鎖爭用頻繁,效能下降
參考上一篇「條件變數實戰」,實現「執行緒 A 每 3 次通知 B」。
| 模式 | 適用場景 | 效能特徵 |
|---|---|---|
| 無同步 | 唯讀共享、Thread-Local | 最快但不安全 |
| 粗粒度鎖 | 簡單計數器、短臨界區 | 鎖爭用高,擴展性差 |
| 細粒度鎖 | 多資料結構獨立操作 | 降低爭用,增加複雜度 |
| 無鎖/原子操作 | 計數器、旗標、環形緩衝 | 最佳擴展性,需記憶體順序知識 |
| 條件變數 | 生產消費、狀態機等待 | 休眠喚醒開銷,避免忙等待 |
// 建立
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 檢視所有執行緒堆疊std::this_thread::get_id()std::lock_guard/unique_lock 防止忘記解鎖std::memory_order