Pthread Mutex
mutex 用來保護多個 thread 共享(shared)的資料,避免 concurrent modification 造成問題。
lock mutex => modify shared data => unlock mutex
mutex 有三種 type:
- fast
- recursive
- error check
操作 mutex 的 function 會依照 type 不同而可能有不同的操作方式。
Initialize Mutex
initial 時,可以用 pthread_mutex_init() 或直接 assign const 指定 mutex 的 type。
1 | int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); |
Lock Mutex
1 | pthread_mutex_lock() |
如果 mutex 是 unlock 狀態,則 lock 該 mutex 且讓該 mutex 為 call phread_mutex_lock() 的 thread 擁有,做完這些後立刻 return。
如果 mutex 正被 lock 住,此 function 會依照不同 type 的 mutex 有不同動作:
fast
calling thread 會 suspend,直到 mutex unlock。沒寫好的話可能造成 deadlock。
recursive
成功並立刻 return。這種 mutex 會記錄它被 lock 幾次,也就是一個 thread 可以 lock 這種 mutex 很多次。要 unlock 這種 mutex 時,也必須 call 相應 lock 次數的 unlock function 才能真正 unlock。
error check
立刻 return,但 errno = EDEADLK。真是個會讓人誤會的 errno 名稱…
EDEADLK 在 man page 的解釋:
the mutex is already locked by the calling thread (``error checking’’ mutexes only).
Try Lock Mutex
1 | pthread_mutex_trylock() |
跟 pthread_mutex_lock() 差不多,差別是這個不會 block 住。
操作 fast mutex 時,trylock() 會立刻 return,而 errno 為 EBUSY。
Unlock Mutex
1 | pthread_mutex_unlock() |
進入此 function 前,mutex 應為 locked 且被 calling thread 擁有。
fast mutex 會直接被 unlock。recursive mutex 需 call 相同於 lock 次數的 unlock 才會真正 unlock。
error check 跟 recursive 的 mutex 會檢查兩個條件:此 mutex 是否為 locked 且被 calling thread 擁有。若有一條件不符合,則不會 unlock,會 return error code。fast mutex 不會做此檢查,所以非擁有此 mutex 的 thread 也可以 unlock 它(這當然不好)。
Ref
- Linux pthread_mutex man page
- PS:Ubuntu 上要裝 glic-doc 才有 pthread 的 man page