2012-09-16 83 views
5

如果一個線程A產生另一個線程B,其目的是寫入一個變量V,然後等待它終止,是否需要內存屏障來確保後續讀取線程A上的V是新鮮的?我不確定在終止/加入操作中是否存在任何隱含的障礙,導致它們變得多餘。加入線程時是否需要內存屏障?

下面是一個例子:

public static T ExecuteWithCustomStackSize<T> 
    (Func<T> func, int stackSize) 
{ 
    T result = default(T); 

    var thread = new Thread(
     () => 
       { 
        result = func(); 
        Thread.MemoryBarrier(); // Required? 
       } 
     , stackSize); 

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

    Thread.MemoryBarrier(); // Required? 
    return result; 
} 

是否是在上面的代碼段中的任一障礙/兩個(或更多)所需?

+4

我懷疑是否需要內存屏障。如果他們那時Thread.Join將是無用的,並且很多人會遇到麻煩。連接等待直到線程完成,這將包括將值分配給變量。 – Despertar

+0

看到這個主題:http://stackoverflow.com/questions/6581848/memory-barrier-generators – Laurijssen

回答

0

從它看起來像不需要他們的文件 -

內存屏障僅在與較弱的存儲排序多處理器系統要求的(例如,採用多個英特爾安騰處理器的系統)。

對於大多數用途,C#鎖定語句,Visual Basic SyncLock語句或Monitor類提供了更簡單的方法來同步數據。

由於您阻止加入,所以更加不必要。

0

您不需要第一個內存屏障。 在訪問已在單獨線程中修改的數據之前,您只需調用它們即可。 既然你不是在'線索'裏面這樣做,你不需要這個電話。

如果您打算保持加入呼叫,您可以擺脫第二個問題。 如果你保留第二個電話,你可以擺脫加入。

3

不,同步機制會生成隱式內存限制。線程修改後的所有數據將在線程連接後可見。

+1

感謝您的回答。任何文件來支持? – Ani

+1

@Ani:在這個源代碼中:http://www.albahari.com/threading/part4.aspx(現在大家都知道),他們幾乎提到每個同步機制都是生成一個fence。他們沒有明確提到'Join',但是因爲它將調用線程置於與'Monitor.Wait'相同的狀態,這是一個強烈的暗示,它也應該生成一個圍欄。此外,還提到了等待「任務」。雖然加入一個線程有點不同,但我期望它提供相同的內存順序保證。 – Tudor

+0

我的確讀過這篇文章,但並不確定這是否確定,因爲像你說的那樣,它沒有明確提及'加入'。 – Ani

相關問題