Причина использования Volatile.Write в начале метода - PullRequest
1 голос
/ 07 мая 2020

Думаю, я немного понял, что именно делают Volatile.Write и Volatile.Read, но я видел несколько примеров, где Volatile.Write используется в начале метода, как в CLR через C# книгу, где Джеффри показывает, как реализовать простую блокировку вращения с помощью Interlocked. Вот код:

struct SimpleSpinLock {
   private int _resourceInUse; // 0 = false, 1 = true

   public void Enter() {
      while (true) {
         if (Interlocked.Exchange(ref _resourceInUse, 1) == 0) return;
      }
   }

   public void Leave() {
      Volatile.Write(ref _resourceInUse, 0); // Why is it here??
   }
}

Вот как предполагается использовать класс:

class SomeResource {
   private SimpleSpinLock _s1 = new SimpleSpinLock();

   public void AccessResource() {
      _s1.Enter();
      // Some code that only one thread at a time can get in..
      _s1.Leave();
   }
}

Итак, как я знаю, Volatile.Write используется для гарантии того, что инструкции, которые находятся над ним будет выполнен точно перед Volatile.Write. Но в методе Leave инструкция только одна и зачем тут использовать Volatile.Write? Наверное, я совершенно неправильно понимаю вещи, поэтому был бы признателен, если бы кто-нибудь мог привести меня на правильный путь.

Ответы [ 2 ]

3 голосов
/ 07 мая 2020

Не стал бы утверждать, что у меня достаточно мозгов, чтобы полностью понять / объяснить это, но вот мои 5 центов. Прежде всего, компилятор может встроить вызов метода Leave, потому что он состоит только из одной строки, поэтому фактическая запись может быть окружена другими инструкциями. Вторичный (и в основном, я полагаю) Volatile документы класса состояние следующее:

В многопроцессорной системе операция энергозависимой записи гарантирует, что значение, записанное в ячейку памяти сразу видно всем процессорам.

Итак, цель этого Volatile.Write вызова - как можно скорее сделать изменение, видимое для другого процессора.

Также см. Ответы на этот вопрос и прочитать о volatile ключевое слово

0 голосов
/ 07 мая 2020

Volatile.Write

"Записывает значение в поле. В системах, которым это необходимо, вставляет барьер памяти, который не позволяет процессору переупорядочивать операции с памятью следующим образом: Если чтение или запись появляется перед этим методом в коде, процессор не может переместить его после этого метода. "

Как я понимаю, это:

Это предложение относится к методу Volatile. (). Итак, «если операция чтения или записи появляется перед Volatile.Write в коде, процессор не может переместить его после Volatile.Write». Это означает, что если другой поток (например) читает / записывает в тот же ресурс, он должен дождаться выполнения Volatile.Write, прежде чем он будет запланирован процессором.

В этом есть смысл, не так ли? Я не думаю, что это вопрос позиции инструкций чтения / записи в методе «хостинга» (Leave), но больше о том, что чтение / запись «происходит» между Enter и Leave.

...