用下面的代码:全部内存屏障和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