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

POSIX 互斥量 API 詳解:初始化、加鎖、解鎖、銷毀與 trylock 非阻塞變體

     編輯:關於C語言

POSIX 互斥量 API 詳解:初始化、加鎖、解鎖、銷毀與 trylock 非阻塞變體

互斥量是多線程同步最基礎的鎖原語。本文系統整理 pthread_mutex_t 相關 5 個核心函數的原型、參數、返回值、行為語義與使用陷阱,為後續同步實戰打基礎。

1. pthread_mutex_init — 初始化

int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);
  • mutex:輸出參數,指向互斥量對象。
  • attr:屬性對象,NULL 使用默認屬性(類型 DEFAULT、非進程共享、非健壯)。
  • 返回 0 成功,非 0 錯誤碼(ENOMEM、EINVAL 等)。
  • 靜態初始化替代:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 僅適用默認屬性。

2. pthread_mutex_destroy — 銷毀

int pthread_mutex_destroy(pthread_mutex_t* mutex);
  • 釋放內核鎖資源,不檢查鎖狀態。若鎖被持有或有線程等待,行為未定義(通常返回 EBUSY)。
  • 銷毀後不可再用,需重新 init。

3. pthread_mutex_lock — 阻塞加鎖

int pthread_mutex_lock(pthread_mutex_t* mutex);
  • 鎖空閒 → 立即獲取,返回 0。
  • 鎖被他線程持有 → 當前線程阻塞,進入等待隊列,直到獲取鎖。
  • 鎖被當前線程持有 → 默認類型下永久阻塞(死鎖)。ERRORCHECK 類型返回 EDEADLK,RECURSIVE 類型允許遞歸(需配對 unlock)。

4. pthread_mutex_trylock — 非阻塞嘗試加鎖

int pthread_mutex_trylock(pthread_mutex_t* mutex);
  • 鎖空閒 → 獲取,返回 0。
  • 鎖被任意線程持有(含自己) → 立即返回 EBUSY,不阻塞。
  • 用於「無法容忍阻塞」場景:實時任務、避免自我死鎖、無鎖演算法重試邏輯。

5. pthread_mutex_unlock — 解鎖

int pthread_mutex_unlock(pthread_mutex_t* mutex);
  • 僅鎖持有者可調用。非持有者調用 → 未定義行為(ERRORCHECK 返回 EPERM)。
  • RECURSIVE 類型需調用與 lock 同次數的 unlock 才真正釋放。
  • 釋放後,等待隊列中優先級最高/最早等待的線程獲取鎖。

屬性對象 pthread_mutexattr_t 進階

pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK); // 開發期推薦
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);  // 需遞歸時
pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); // 實時系統優先級繼承
pthread_mutex_init(&mutex, &attr);
pthread_mutexattr_destroy(&attr);

常見錯誤總結

  1. 未初始化直接使用 → 崩潰/未定義行為。
  2. 忘記 unlock → 永久阻塞其他線程。
  3. 非持有者 unlock → 數據結構損壞。
  4. 銷毀仍被持有的鎖 → 資源洩漏/崩潰。
  5. 默認鎖類型下重複 lock → 隱蔽死鎖,極難復現。

總結

互斥量 5 大 API 構成「初始化→加鎖/解鎖→銷毀」生命周期。理解 lock 阻塞語義、trylock 非阻塞語義、鎖類型對重複加鎖行為的影響,是編寫正確多線程代碼的前提。開發階段強烈建議使用 ERRORCHECK 類型自動檢測誤用。

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