2012-02-01 42 views
0

前一個線程鎖定一個互斥體之前已經鎖定互斥,我要檢查是否已經得到了對互斥鎖,所以我不能做到這一點檢查線程已經鎖定

Acquire mutex 
Acquire mutex 

// do something here 

Release mutex 

// still has mutex lock at this point!! 

我知道我可以在這裏使用布爾,但想知道是否已經存在。

謝謝。

回答

0

如果您使用的是特定於平臺的(Win32?)互斥實現 - 那麼您應該諮詢該平臺的文檔。

如果您使用C++ 11標準的互斥體 - 的std ::互斥體,切換到標準:: recursive_mutex代替。請注意,每次調用lock()時都需要調用unlock()。

+2

「閱讀文檔」不是Stack Overflow答案。 – 2017-02-22 07:56:50

0

調查RAII。這會阻止你擔心這個問題。

+0

暗示有一個額外的布爾的,如果把它包在一個類/結構它的鎖定與否?...(關於RAII是什麼,在5分鐘的谷歌之後,這個評論可能有點不成熟) – Cheetah 2012-02-01 12:52:51

+0

+1。保羅的建議很好。該課程將有一個成員 - 一個互斥體(參考)。在構造函數中獲取,在析構函數中釋放。異常安全,不需要任何布爾。在第一個答案這裏一看一個例子:http://stackoverflow.com/questions/161177/does-c-support-finally-blocks-and-whats-this-raii-i-keep-hearing-about – 2012-02-01 13:10:50

+2

我沒有看到這將如何幫助這裏。遞歸調用不會導致在下一次調用之前觸發RAII發佈方面。 – 2012-02-01 14:40:36

0

你用什麼API? 這很重要,因爲如果它是例如Win32 API在一個互斥體上的一個線程中對WaitForSingleObject的雙重調用,您不必調用兩次ReleaseMutex。

然而,這是很危險的代碼嗎

1

太長了評論,所以道歉,這是一個答案..

IMO,這就要求遞歸鎖定任何設計很可能終結鼻守護進程。重新設計您的代碼,以便相同的線程不必多次獲取相同的鎖。一個好的做法是永遠不要從其他公用函數(也應該鎖)中調用公共函數(應該鎖),所有私有函數都不應該鎖 - 即只能通過公用方法調用它們(被鎖定)。

於是重新組織你的代碼調用在同一個線程上下文方法有一個入口點到你的對象,然後把鎖,以及任何後續私有函數調用可以將此鎖下運行。這種方法存在一些缺點(例如對於順序函數調用的多重鎖定操作 - 但是如果這通過分析被證明是瓶頸,那麼採用通過成員暴露互斥體的模式,並且如已經提到的一個人已經使用RAII鎖定該鎖的功能,通話時長。)

所有功能於一切,如果你能避免遞歸互斥體...

+0

但遞歸互斥確實存在。 – 2012-02-01 14:42:19

+0

@ edA-qamort-ora-y,對於那些自虐足以冒險走下那條路線的人......;) – Nim 2012-02-01 14:43:54