Вопрос

В следующем примере кода, является ли барьер памяти в Фанка Требуется ли считывать самое современное значение?

class Foo
{
   DateTime m_bar;

   void FuncA() // invoked by thread X
   {
      Thread.MemoryBarrier(); // is required?
      Console.WriteLine(m_bar);
   }

   void FuncB() // invoked by thread Y
   {
       m_bar = DateTime.Now;
   }       
}

РЕДАКТИРОВАТЬ: Если нет, то как я могу гарантировать, что Funca будет читать самую последнюю ценность? (Я хочу убедиться, что недавнее значение фактически хранится в кэше процессора) [Wihout с использованием замков

Это было полезно?

Решение 5

Это на самом деле не имеет значения, так как на 32 -битных архитектурах можно прочитать разорванное в такой ситуации

Другие советы

Для меня выглядит как большая "нет". Thread.MemoryBarrier () только синхронизирует доступ к памяти в потоке, который его реализовал.

От MSDN:

Процессор, выполняющий текущий поток, не может переупорядочить инструкции таким образом, чтобы память обращалась к вызову в MemoryBarrier, выполняющую после доступа к памяти, которые следуют за вызовом в MemoryBarrier.

Я предлагаю вам сохранить DateTime как количество клещей (это типа «длинная», т.е. int64), вы можете легко преобразовать из клещей (New DateTime (Ticks)) и в Ticks (myDateTime.ticks). Затем вы можете использовать Interlocked.READ для чтения и взаимосвязанный.

Да, барьер памяти необходим, чтобы вы могли получить наиболее актуальное значение.

Если барьер памяти отсутствует, то поток X может прочитать значение M_BAR из собственной линии кэша, в то время как это значение не было записано обратно в основную память (изменение было локально для потока Y). Вы можете достичь того же эффекта, объявив переменную нестабильной:

Волатильный модификатор обычно используется для поля, доступ к которому доступ к нескольким потокам без использования оператора блокировки для сериализации доступа. Использование летучего модификатора гарантирует, что один поток извлекает наиболее современное значение, записанное другим потоком.

Хорошая запись по этому вопросу (вероятно, лучший) - это Джо Даффи: Нестабильное чтение и писание, и своевременность

Барьер памяти наступает то же самое, что и блокировка Wat, гарантируя, что поле получит свое последнее значение от памяти при входе в блокировку и будет записано в память перед выходом из блокировки.
Убедиться, что значение поля всегда читается или записывается в память и никогда не оптимизировалась, читая или написав его сначала в кэше ЦП, также может быть достигнуто с помощью летучих ключевых слов.
Если примитивные интегральные типы и эталонные типы DateTime не могут быть кэшированы в регистрах процессора AD, поэтому не нужно (и не может) быть объявлено с помощью нестабильного ключевого слова.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top