完全内存屏障和ExclusiveReceiverGroup

时间:2011-02-27 08:47:40

标签: c# concurrency robotics memory-barriers ccr

使用以下代码:

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生成完整的内存屏障?由于dispatcherQueue不使用Dispatcher,因此线程池将调用AcceptReceiverGroup的Receiver注册中的处理程序。我已经读过线程池为它调用的回调生成一个内存屏障,但是这只能保证回调引用本身的新鲜度吗?

ExclusiveReceiverGroup不与任何其他代码同时运行,因此使用calculateResult.Result递增totalSum不必是原子的。我知道Interlocked.Add会隐式生成一个完整的栅栏,但我只是想看看我是否可以在不使用它的情况下逃脱。

这是一个理论问题。我实际上没有像上面的示例代码那样的代码,并且我没有任何用于此类代码的用例。所以,我想避免“使用Interlocked.Add以防万一”的答案。这更像是“让我们学到新东西”的问题。

1 个答案:

答案 0 :(得分:0)

我的理解是,因为ExclusiveReceiverGroup在任何时候都只有效地执行其委托的单个线程实例,所以不需要(进一步)内存屏障。 ExclusiveReceiverGroup的重点是解决共享状态的有害问题,因此它是专门设计的,因此可以避免锁定。这与您正在使用的池/调度程序无关。