2011-09-14 62 views
8

假設線程成功調用pthread_mutex_lock,那麼在同一個線程中調用pthread_mutex_unlock仍然可能會失敗?如果是這樣,除了放棄線程之外,你能否真正做些什麼?你如何處理pthread_mutex_unlock失敗?

if(pthread_mutex_lock(&m) == 0) 
{ 
    // got the lock, let's do some work 

    if(pthread_mutex_unlock(&m) != 0) // can this really fail? 
    { 
     // ok, we have a lock but can't unlock it? 
    } 
} 

this page,用於pthread_mutex_unlock()可能的錯誤是:

[EINVAL] mutex指定的值不是指一個初始化 互斥對象。

如果鎖定成功,則這不可能失敗。

[EAGAIN] 互斥量,因此無法獲取,因爲互斥量 遞歸鎖的最大數量已超出。

真的嗎?解鎖?

[EPERM] 當前線程不擁有該互斥:如果

的調用pthread_mutex_unlock()函數可能會失敗。

再次,如果鎖定成功,那麼這也不應該發生。

所以,我的想法是,如果有一個成功的鎖,那麼在這種情況下解鎖應永不失敗,使錯誤檢查和後續處理代碼毫無意義。

回答

2

從man頁面調用pthread_mutex_unlock:

The pthread_mutex_unlock() function may fail if: 

EPERM 
The current thread does not own the mutex. 

These functions shall not return an error code of [EINTR]. 

如果您認爲該男子頁,它似乎是你的錯誤的情況下也不會發生。

+0

謝謝,這幾乎是我的想法。我更新了這個問題,希望能夠讓我更清楚爲什麼要問。在接受答案之前,我想堅持看看能否獲得其他意見。 –

2

在你哭泣的「勝利」之前。我在這個頁面上找到了我的一個程序在pthread_mutex_unlock(在HP-UX而不是Linux上)失敗的原因。

if (pthread_mutex_unlock(&mutex) != 0) 
    throw YpException("unlock %s failed: %s", what.c_str(), strerror(errno)); 

經過數百萬次的快樂處決,我失敗了。 errno是EINTR,雖然我剛纔發現我不應該檢查errno,而是返回值。但是,儘管如此,返回值不是0。我可以從數學上證明,在那個地方我擁有一個有效的鎖。

所以,讓我們只是說你的理論處於壓力之下,雖然需要更多的研究;-)

+0

太棒了!或者可能不太棒。 :-)這正是我正在尋找的那種反饋。你能重現這個錯誤還是一次性的?因爲'pthread_mutex_unlock()'不應該返回'EINTR',在'errno'或其他地方,所以知道實際返回值是什麼會很有趣。 –

+0

我一直無法重現它。我修正了日誌記錄以顯示實際返回值,而不是errno。下一次它發生(我希望不會),我會讓你知道它到底是什麼;-) – geert3

+2

小更新:我一直有失敗解鎖的虛假事件,返回值== 1,意思是「不是所有者」。這原來是一個非常微妙的錯誤。 我把我所有的鎖包裝在對象中(析構函數解鎖)。當鎖定與對象的範圍一起自動結束時,這很方便。 在這個函數中我調用了thread_exit()。手冊頁說你不能在thread_exit()之後使用自動變量。這正是我的鎖封裝對象的析構函數正在做的(隱式稱爲AFTER thread_exit)。 – geert3