pthread_mutex_unlock()函數將釋放由互斥量引用的互斥對象。但是,釋放互斥體的方式取決於互斥體的類型屬性。如果調用pthread_mutex_unlock()時互斥體引用的互斥體對象上存在線程阻塞,導致互斥體變爲可用,則調度策略應確定哪個線程將獲取互斥體。
如果互斥體類型爲PTHREAD_MUTEX_NORMAL,則不應提供死鎖檢測。試圖重新鎖定互斥鎖會導致死鎖。如果線程試圖解鎖未鎖定的互斥鎖或解鎖的互斥鎖,則會導致未定義的行爲。
如果互斥類型爲PTHREAD_MUTEX_ERRORCHECK,則應提供錯誤檢查。如果線程試圖重新鎖定已鎖定的互斥鎖,則應返回錯誤。如果線程試圖解鎖未鎖定的互斥鎖或已解鎖的互斥鎖,則應返回錯誤。
如果互斥體類型爲PTHREAD_MUTEX_RECURSIVE,那麼互斥體應保持鎖定計數的概念。當線程第一次成功獲取互斥鎖時,鎖定計數應設置爲1。每次線程重新鎖定此互斥鎖時,鎖定計數應遞增1。每次線程解鎖互斥鎖時,鎖定計數應減1。當鎖計數達到零時,互斥量將可供其他線程獲取。如果線程試圖解鎖未鎖定的互斥鎖或已解鎖的互斥鎖,則應返回錯誤。
如果互斥體類型爲PTHREAD_MUTEX_DEFAULT,則嘗試遞歸鎖定互斥體會導致未定義的行爲。如果未被調用線程鎖定,則試圖解鎖互斥鎖會導致未定義的行爲。嘗試解鎖互斥鎖,如果未鎖定,則會導致未定義的行爲。
我通常更喜歡使用PTHREAD_MUTEX_RECURSIVE互斥量,因爲在這種情況下,互斥量在計數達到零時可用,並且調用線程不再在此互斥鎖上有任何鎖定。
如果互斥體上存在大量爭用,則解鎖互斥體可能會很慢,因爲部分解鎖工作正在喚醒等待互斥體的任何線程。 – caf
我認爲如果將'pthread_mutex_unlock()'調用移動到'pthread_cond_signal()'的調用上方,將會看到結果會很有趣。沒有要求在發信號通知條件變量時(僅在等待它時)持有互斥體,並且我懷疑發生了什麼事情是信號引起互斥體的爭用,因爲立即釋放的線程會嘗試獲取互斥體,信令線程仍然成立。 –
@MichaelBurr好點!我測試了你的建議,現在這個程序快了大約40%。 –