2011-08-30 26 views
5

在這個線程在線圖書:http://www.albahari.com/threading/part4.aspx瞭解非阻塞線程同步和Thread.MemoryBarrier

那裏有中Thread.MemoryBarrier()

class Foo 
{ 
    int _answer; 
    bool _complete; 

    void A() 
    { 
    _answer = 123; 
    Thread.MemoryBarrier(); // Barrier 1 
    _complete = true; 
    Thread.MemoryBarrier(); // Barrier 2 
    } 

    void B() 
    { 
    Thread.MemoryBarrier(); // Barrier 3 
    if (_complete) 
    { 
     Thread.MemoryBarrier();  // Barrier 4 
     Console.WriteLine (_answer); 
    } 
    } 
} 

一個例子,我們有一個討論是否有任何線程阻塞回事與否?

即時通訊思想有一些,特別是考慮到

一個完整的圍欄是以2010年的時代桌面上,約十納秒。

在另一方面,全柵欄只應該disable instructions reodering and caching它通過它的聲音沒有資格作爲線程阻塞,(不像lock其中其明確表示線程等待其他繼續之前,就被擋住了,解除鎖定在這段時間)

關於該線程「阻塞狀態」。 IM在是否線程方面不說話或投入阻塞狀態不行,但是否有一些線程同步發生,這意味着一個線程是不是能,而其他不讓它這樣做跑,藉助於MemoryBarrier在這種情況下。

而且我還想得到明確瞭解每個屏障實現。例如,障礙2 - 它如何提供新鮮度保證,以及它如何與障礙物3連接?如果有人會詳細解釋什麼是每個屏障的目的(如果1或2或3或4不在那裏可能會出錯),我認爲id大大提高了我對此的理解。

編輯:它現在大多數清楚了什麼1,2,3做什麼。然而,這3個不是還不清楚。

回答

5

指令需要時間執行的事實而不是意味着一個線程被阻塞。當一個線程被專門設置爲阻塞狀態時會被阻塞,而MemoryBarrier()則不會。

實際上阻止指令重新排序和緩存刷新的處理器指令需要時間,因爲它們必須等待緩存再次變得一致。在此期間,該線程仍被視爲運行。

更新:那麼讓我們來看看示例中實際發生的情況以及每個內存屏障實際上做了什麼。

正如鏈接所說,1和4確保生成正確的答案。這是因爲1確保將回答刷新到內存中,並且4確保讀取緩存在檢索變量之前被刷新。

2和3確保如果A先運行,那麼B總是打印答案。屏障2確保將true的寫入刷新到內存,並且屏障3確保在測試_complete的值之前刷新讀取的標記。

緩存和內存刷新應該足夠清晰,所以讓我們看看指令重新排序。編譯器,CLR和CPU知道他們可以重新排序指令的方式是按順序分析一組指令。當他們在序列的中間看到屏障指令時,他們知道指令不能跨越該邊界移動。這確保了除了緩存新鮮度之外,指令按正確的順序發生。

+0

確定它並不意味着直接,我只是認爲它可能被認爲是一種證據,它的邏輯命令需要時間來執行。 –

+0

@Valentin它可以被視爲證據,但它只是在這裏的情況:) – dlev

+0

沒問題,看看我的編輯在問題的結尾,而當我們在它的時候,鎖定語句把線程置於阻塞狀態(只是爲了澄清該線程阻塞狀態定義)? –