2010-09-25 88 views
2

好的。我想有兩個線程在運行。當前代碼:C#多線程

public void foo() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

    public void bar() 
    {  
      lock(this) 
      { 
       while (stopThreads == false) 
       { 
        foreach (var acc in myList) 
        { 
        // process some stuff 
        } 
       } 
      } 
    } 

兩者都訪問相同的List,問題是第一個線程「foo」沒有釋放我猜的鎖;因爲「bar」僅在「foo」完成時纔開始。謝謝

+0

是的,bar只會在foo完成後啓動,這就是鎖的工作方式,您應該提供更多關於如何讓代碼運行的細節。 – 2010-09-25 11:24:01

+0

讀取semaphore/mutex的定義,然後移除鎖定 – 2010-09-25 11:51:21

回答

3

是的,這就是鎖的設計工作。

鎖關鍵字標誌着一個語句塊作爲通過獲得互斥鎖定給定對象,執行語句,然後解除鎖定的一個關鍵部分。

相互排斥意味着最多隻能有一個線程在任何時間持有鎖。

鎖定這是一個壞主意,並且不鼓勵。您應該創建一個私有對象並對其進行鎖定。爲了解決你的問題,你可以鎖定兩個不同的對象。

private object lockObject1 = new object(); 
private object lockObject2 = new object(); 

public void foo() 
{  
    lock (lockObject1) 
    { 
     // ... 
    } 
} 

public void bar() 
{  
    lock (lockObject2) 
    { 
     // ... 
    } 
} 

另外,您可以重複使用相同的鎖,但將它的循環中,使每個環都有機會進行:

while (stopThreads == false) 
{ 
    foreach (var acc in myList) 
    { 
     lock (lockObject) 
     { 
      // process some stuff 
     } 
    } 
} 

不過我建議你花一些時間來了解什麼是繼續而不是重新排序代碼行直到它看起來在你的機器上工作。編寫正確的多線程代碼很困難。

對於停止線程我會推薦這篇文章:

+0

stopThreads變量怎麼樣,它不是線程安全的,可能是他得到了完全錯誤的結果。 – TalentTuner 2010-09-25 11:18:42

+0

@saurabh:它可能會變得不穩定。或者它可以被製成一個線程安全的屬性。 – 2010-09-25 11:28:49

+0

謝謝,那工作。 – foobar 2010-09-25 14:52:32

0

你的問題是,你有一個非常粗糙的鎖定工作。 Foo和Bad都基本不兼容,因爲誰先啓動就停止另一個完成工作循環。

它應該雖然只鎖定,但它需要的東西出列表。根據定義,Foreach在這裏不起作用。你要提出第二個清單,並讓每個線程刪除頂部項目(同時鎖定),然後處理它。

基本上是:

  • 的foreach是不行的,因爲兩個線程將通過compelte列表運行
  • 其次,鎖具必須是,他們只需要同時鎖定顆粒狀。

在你的情況下,你鎖定foo只會在foo完成時被釋放。

1

既然你不是真的在問一個問題,我建議你應該閱讀關於線程工作原理的教程。 .Net特定指南可以是found here。它包含「入門」,「基本同步」,「使用線程」,「高級線程」和「並行編程」等主題。

另外,您正在鎖定「this」。該Msdn說:

一般情況下,避免鎖定在公共 類型,或超出你的代碼的 控件實例。共同構建lock (this)lock (typeof (MyType)),並 lock ("myLock")違反本 方針:

  • lock (this)是一個問題,如果 實例可以被公開訪問。

  • lock (typeof (MyType))是一個問題,如果 MyType是可公開訪問。

  • lock(「myLock」)是因爲 使用 相同的字符串的處理的任何其他代碼,將共享相同的 鎖的問題。

最佳做法是定義一個私人 對象鎖定或私有靜態 對象變量,以保護共同 所有實例的數據。