2012-05-01 220 views
1

「Mutex類強制線程標識,因此互斥可以通過收購它的線程纔會釋放。相反,Semaphore類不強制線程標識。」釋放互斥鎖。

這是MSDN介紹說。但根據我的問題Application exception is thrown,我試圖釋放一個互斥體,即使我沒有獲得它。它在下一個線程執行時向我展示了一個異常。這是否意味着沒有訪問互斥體的線程釋放它?有人可以幫助我理解這個概念,如果我犯了什麼錯誤,請指示我。

回答

1

就像文檔說的那樣,ApplicationException被拋出是因爲沒有擁有互斥鎖的線程試圖釋放它。這並不意味着互斥體被釋放,只是試圖釋放它的線程並不擁有它。

var mutex = new Mutex(); 
mutex.WaitOne(); 
var thread = new Thread(() => 
    { 
     try 
     { 
      mutex.ReleaseMutex(); //This will throw ApplicationException 
     } 
     catch (ApplicationException ex) 
     { 
      Console.WriteLine("Failed to release mutex"); 
     } 
    }); 

thread.Start(); 
thread.Join(); 

mutex.ReleaseMutex(); //No exception will be thrown here 

在這個例子中,初始線程創建互斥量並獲取它。第二個線程將被啓動,試圖釋放它並失敗。失敗後,擁有的線程將釋放它。

更新

在你前面的問題,一定要注意你正在運行多線程代碼和相同的競爭條件存在於每一個線程是很重要的。多個線程可能無法在一個線程持有它時獲取互斥體,因此多個線程同樣無法釋放它。以下面的執行路徑爲例。

  • 線程1獲取互斥鎖。
  • 線程2無法獲取互斥鎖,因爲線程1擁有它。
  • 線程3無法獲取互斥鎖,因爲線程1擁有它。
  • 線程3嘗試釋放互斥鎖,拋出一個ApplicationException因爲它不擁有它。
  • 線程1釋放互斥鎖。
  • 線程2嘗試釋放互斥鎖,拋出ApplicationException因爲它不擁有它。

線程3在未能釋放互斥鎖時爆炸的事實與線程2 也通過執行相同的事情而爆發的事實沒有關聯。

+0

如果你可以請執行我以前的問題中的代碼。 U會注意到下一個線程會引發異常。 – Shrikey

+0

@Shrikey更新了我的答案,以解決您以前的代碼。 –

+0

但是,如果你可以檢查輸出的代碼。應用程序異常在線程釋放不擁有它的互斥體後不會立即拋出。異常延遲:( – Shrikey

0

關於互斥體的概念,您可以將其想象爲抽屜,以及擁有互斥鎖的線程作爲持有該抽屜的鍵的人。只有持有抽屜鑰匙的人才能解鎖它,因此只有獲得該互斥鎖的線程才能釋放它。

當您嘗試從不擁有互斥鎖的線程釋放互斥鎖時,就像有人試圖用假鑰匙打開其他人的抽屜,因此引發異常來抓住竊賊!

這就是所有的互斥量,它可以防止多線程執行「受保護的代碼」(在抽屜內)。它的名字來自「互斥」,意思是一次一個線程。