Почему этот код не демонстрирует неатомарность чтения / записи?

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

private static double _d;

[STAThread]
static void Main()
{
    new Thread(KeepMutating).Start();
    KeepReading();
}

private static void KeepReading()
{
    while (true)
    {
        double dCopy = _d;

        // In release: if (...) throw ...
        Debug.Assert(dCopy == 0D || dCopy == double.MaxValue); // Never fails
    }
}

private static void KeepMutating()
{
    Random rand = new Random();
    while (true)
    {
        _d = rand.Next(2) == 0 ? 0D : double.MaxValue;
    }
}

To к моему удивлению, утверждение отказалось потерпеть неудачу даже после целых трех минут исполнения. Что дает?

  1. Тест неверен.
  2. Конкретные временные характеристики теста делают маловероятным / невозможным, что утверждение не удастся.
  3. Вероятность настолько мала, что мне придется запускать тест намного дольше, чтобы сделать его
  4. CLR обеспечивает более строгие гарантии атомарности, чем спецификация C #.
  5. Моя ОС / оборудование предоставляет более строгие гарантии, чем CLR.
  6. Что-то еще?

Конечно, я не знаю ' Я намерен полагаться на любое поведение, которое явно не гарантируется спецификацией, но мне хотелось бы более глубокого понимания проблемы.

К вашему сведению, я запускал это как в Debug, так и в Release (изменяя Debug.Assert ] в if (..) throw ) профили в двух разных средах:

  1. 64-разрядная Windows 7 + .NET 3.5 SP1
  2. 32-разрядная Windows XP + .NET 2.0

ИЗМЕНИТЬ : Основано на предложении Дэна Брайанта: использование long вместо double практически мгновенно разрывает его.

11
задан Community 23 May 2017 в 12:26
поделиться