用下面的代碼:全部內存屏障和ExclusiveReceiverGroup
var dispatcherQueue = new DispatcherQueue();
long totalSum = 0;
Arbiter.Activate(
dispatcherQueue,
Arbiter.Interleave(
new TeardownReceiverGroup(),
new ExclusiveReceiverGroup(
Arbiter.Receive<ComputationCompleteResult>(
true,
portSet,
computationResult => totalSum += computationResult.Result
),
new ConcurrentReceiverGroup(
// Imagine that there is a persistent Receiver registered here
)
)
);
我需要生成約totalSum + = computationResult.Result完全內存屏障? ExclusiveReceiverGroup的Receiver註冊中的處理程序將由線程池調用,因爲dispatcherQueue不使用分派器。我讀過線程池爲它所調用的回調生成一個內存屏障,但這是否確保了回調引用本身的新鮮度?
ExclusiveReceiverGroup不會與任何其他代碼同時運行,因此通過calculateResult.Result遞增totalSum不必是原子的。我知道Interlocked.Add隱含地產生了一個完整的柵欄,但我只想看看我是否可以在沒有使用的情況下離開。
這是一個理論問題。實際上我沒有像上面的示例代碼那樣的任何代碼,並且我沒有任何這種代碼的用例。所以,我想避免「使用Interlocked.Add以防萬一」的答案。這更多的是「讓我們學點新東西」的問題。
你說得對,但是如果我們在DispatcherQueue中使用Dispatcher,似乎還是會產生內存障礙。分派器在它創建的線程上調用回調,對此沒有內存屏障gaurantees(我相信)。在這種情況下,我們必須自己生成內存屏障,以確保我們使用的totalSum的值是來自主內存的全新副本。如果我們使用沒有Dispatcher的DispatcherQueue,我們不必生成完整的內存屏障,因爲ThreadPool爲我們做了這些。這有意義嗎? – 2011-03-04 16:54:05