2010-11-17 67 views
2

晚上好同胞堆垛機,我有一個互斥體和螺紋相關問題有關Visual Basic中 - 使用嵌套互斥鎖在一個線程應用程序 - 風險和建議

// ¦ = Run one or the other per call to routine 

|GROUP A| GROUP B | 
| A & B GROUP MUTEX | 
|=======|============| 
|A1 & A2¦ B1 & |B2|B3| 
       |MUTEX| 
       |==|==| 
       |B2¦B3| 

形勢

是這種情況下的安全還是可行?

我在VB.NET中有5個子例程,我可以以異步線程方式在兩組中包含單獨的子集運行它們。

但是,正如上面可怕的粗糙的文本 - 圖形所示,互斥體在子集B上的工作也是如此。

邏輯

A,B組有等待的海誓山盟如果作業已經開始在任 - A & B GROUP MUTEX有助於保持這檢查。

組內A組都可以同時開始例程(B將不得不等待A1和A2都完成)。

B組,以B1,B2和B3可以在相同的時間或者B2和B3但B2和B3不能同時運行,因此該子集MUTEX檢查運行B1。

更新: @pstrjds做用好點同步鎖定,而不是:我使用的原因互斥的,而不是同步鎖定是由於這樣的事實,我需要這個過程中多用戶安全的,因爲內子例程是很多基於SQL和數據的操作,它們需要程序被鎖定,同時在3個不同的服務器上的不同數據庫上執行多個SQL事務以同時並安全地更新它們 - SQL中的事務處理已完成且運行良好分解的僞代碼。 @pstrjds說這是使用從一個類生成的線程是正確的,但是在它調用Web服務(B2組和B3組中的一部分工作)的子例程中,它更新了單獨的第三方服務器。 </Wall-o-Text>

僞代碼

不幸的是確切的代碼是很長,但我使用這種結構:

Sub AGroup_Method() 

    Dim bln_FirstInstance As Boolean 

    Using objABMutex As New Mutex(True, "Global\AB_MutexLock", blnFirstInstance) 
     If bln_FirstInstance Then 
      //Start Threads for subroutine A1 And then A2 
      StartThread_A1() 
      StartThread_A2() 
     Else 
      //Post that Group A subroutine needs to wait for Group B 
     End If 
    End Using 
End Sub 

Sub BGroup_Method(Byval p_blnRunBTwo as Boolean) 

    Dim bln_FirstInstance As Boolean 
    Dim blnBGroup_FirstInstance As Boolean 

    Using objABMutex As New Mutex(True, "Global\AB_MutexLock", bln_FirstInstance) 
     If bln_FirstInstance Then 
      //Do subroutine group B 

      //Start B1 
      StartThread_B1() 

      Using objBGroupMutex As New Mutex(True, "Global\BGroup_MutexLock", blnBGroup_FirstInstance) 
       If p_blnRunBTwo 
        If blnBGroup_FirstInstance Then 
         //Wait for mutex from B3 and then run B2 
         StartThread_B2 
        End If 
       Else 
        If blnBGroup_FirstInstance Then 
         StartThread_B3 
        End If 
       End If 
      End Using      
     Else 
      //Post that Group B subroutine needs to wait for Group A 

     End If 

    End Using 

End Sub 

幫助!

我想問的是如果互斥體嵌套是一個可能的問題,如果它是不好的練習whatnots,並有沒有更好的方式來實現這個使用線程系統。

+1

除非你需要這些互斥體是進程間,你就不需要使用命名的互斥體,而你只需要「全球\」,如果你使用的是命名的互斥體在您需要保護的東西終端服務環境在同一個系統上的多個用戶(即寫入日誌文件或類似這種事情) – pstrjds 2010-11-17 13:36:45

+0

@pstrjds您是與進程間的一聲,原來原因互斥體,以允許它通過對每個用戶同時運行系統,帶有標誌A組,B2或B3選項的標誌。寫日誌也是用戶名和會話相關的,所以它們被安全地命名而不會出現鎖定問題。 – 2010-11-17 14:05:54

+0

剛擡起頭對全球命名的互斥體,然後,你可以跑進不會讓他們創建互斥用戶的權限問題,你還需要有適當的MutexAccessRule創建您的具體情況,以便其他用戶比創造者是能夠訪問它。 – pstrjds 2010-11-17 14:38:48

回答

1

我不認爲你在這裏使用互斥鎖,但是如果所有的代碼都在同一個類中,並且你只是在該類中產生工作線程(我將它從僞代碼你提出的),你可以逃脫只聲明兩個對象,並使用SyncLock來處理訪問。這應該是比使用互斥更多表演(再次假設所有這些代碼是在同一類和線程從類啓動,你不需要進程間序列化)

​​

編輯:根據建議添加了有關已命名互斥鎖的信息: 如果您使用的是全局命名的互斥鎖,則如果運行代碼的用戶訪問權限受限(例如以訪客用戶身份運行),則可能會遇到權限問題。另一個問題是創建適當的MutexAccessRule,以便其他用戶在創建後可以訪問它。在C#代碼示例:

Mutex mutex = null; 
bool exists = true; 

// Using try catch since as far as I know there is no other way to check if 
// a mutex exists, but to open it and catch the exception, this may be changed 
// in .Net 4.0, I originally wrote this targeting 2.0 
try 
{ 
    mutex = Mutex.OpenExists(@"Global\MyMutexName"); 
} 
catch 
{ 
    exists = false; 
} 

if (!exists) 
{ 
    SecurityIdentifer sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null); 
    MutexAccessRule rule = new MutexAccessRule(sid, MutexRights.FullControl, 
     AccessControlType.Allow); 
    MutexSecurity security = new MutexSecurity(); 
    security.AddAccessRule(rule); 

    bool createdNew = false; 
    mutex = new Mutex(false, @"Global\MyMutexName", out createdNew, security); 
} 

上面的代碼將創建不限於創建它的用戶一個互斥體,如果你是在終端服務環境,在運行相同程序的多個人來說這是非常重要的同時。你可能會比我在那裏限制某些權限好得多(真的是我幾乎沒有任何限制地創建它),但沒有你可以讓人創建互斥體,並且人B拋出異常,因爲他們不能訪問互斥體被人A.

+0

注意使用同步鎖定,如果這不是進程間的情況,那麼這會很有用。我會在我的問題中澄清進程間的情況!一個有效的和有用的答案不會少。 – 2010-11-17 14:07:37

+0

它是進程間也拋出我的另一個想法,你可能需要一系列的事件句柄。我不得不同意@Hans,目前還不清楚究竟發生了什麼。如果它們在其他進程中運行,則可能需要查看來回傳遞消息以獲取同步。 – pstrjds 2010-11-17 14:16:53

+0

測試時,互斥鎖在一個用戶中沒有問題,但在更改爲此類互斥體後,該過程可安全地跨多個用戶使用,且不會死鎖 - 接受爲答案。 – 2010-11-18 09:12:17

1

是創建的,這是一個不好的做法。我幾次瀏覽了這個問題,但我並不完全知道如何給出一個好的答案。這是一個問題,如果你不能輕易解釋你的鎖定模型,並且你有麻煩提出了一個清晰的圖像,那麼推斷可能的狀態置換的數量也變得非常困難。

不能夠推理所有可能的狀態排列有一個潛在的非常討厭的運行時間延長。僵局。