在code review中,我會發現不少人喜歡在pthread_mutex_lock()和pthread_mutex_unlock(()之間調用 pthread_cond_signal或者pthread_cond_broadcast函數,從邏輯上來講,這種使用方法是徹底正確的。可是在多線程環境中,這種使用方法多是低效的。posix1標準說,pthread_cond_signal與pthread_cond_broadcast無需考慮調用線程是不是mutex的擁有者,也就是說,能夠在lock與unlock之外的區域調用。若是咱們對調用行爲不關心,那麼請在lock區域以外調用吧。這裏舉個例子:
咱們假設系統中有線程1和線程2,他們都想獲取mutex後處理共享數據,再釋放mutex。請看這種序列:
1)線程1獲取mutex,在進行數據處理的時候,線程2也想獲取mutex,可是此時被線程1所佔用,線程2進入休眠,等待mutex被釋放。
2)線程1作完數據處理後,調用pthread_cond_signal()喚醒等待隊列中某個線程,在本例中也就是線程2。線程1在調用pthread_mutex_unlock()前,由於系統調度的緣由,線程2獲取使用CPU的權利,那麼它就想要開始處理數據,可是在開始處理以前,mutex必須被獲取,很遺憾,線程1正在使用mutex,因此線程2被迫再次進入休眠。
3)而後就是線程1執行pthread_mutex_unlock()後,線程2方能被再次喚醒。
從這裏看,使用的效率是比較低的,若是再多線程環境中,這種狀況頻繁發生的話,是一件比較痛苦的事情。因此以爲,若是程序不關心線程可預知的調度行爲,那麼最好在鎖定區域之外調用他們。 php
對於
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime);
,必定要在mutex的鎖定區域內使用。
若是要正確的使用pthread_mutex_lock與pthread_mutex_unlock,請參考
pthread_cleanup_push 和pthread_cleanup_pop宏,它可以在線程被cancel的時候正確的釋放mutex! html