Полный барьер памяти и ExclusiveReceiverGroup - PullRequest
0 голосов
/ 27 февраля 2011

Со следующим кодом:

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?Обработчик в регистрации Receiver группы ExclusiveReceiverGroup будет вызываться пулом потоков, поскольку dispatcherQueue не использует Dispatcher.Я читал, что пул потоков создает барьер памяти для обратных вызовов, которые он вызывает, но гарантирует ли это только свежесть для самой ссылки обратного вызова?

ExclusiveReceiverGroup не запускается одновременно с любым другим кодом, поэтому увеличение totalSum наcomputationResult.Result не должен быть атомарным.Я знаю, что Interlocked.Add неявно создает полный забор, но я просто хочу посмотреть, смогу ли я уйти, даже не используя это.

Это теоретическая проблема.На самом деле у меня нет кода, подобного приведенному выше, и у меня нет вариантов использования такого кода.Итак, я хочу избежать ответов «использовать Interlocked.Add на всякий случай».Это скорее вопрос «давайте узнаем что-то новое».

1 Ответ

0 голосов
/ 04 марта 2011

Насколько я понимаю, поскольку ExclusiveReceiverGroup эффективно когда-либо выполняет только один экземпляр потока своего делегата в любой момент времени, (далее) барьер памяти не требуется. Весь смысл ExclusiveReceiverGroup состоит в том, чтобы решить пагубную проблему общего состояния, и поэтому он специально разработан, чтобы можно было избежать блокировки. Это будет независимо от того, какой пул / диспетчер вы используете.

...