Вам будет очень трудно воспроизвести эту ошибку. На самом деле, я бы сказал, что вы никогда не сможете воспроизвести его с помощью .NET Framework. Причина в том, что реализация Microsoft использует сильную модель памяти для записи. Это означает, что записи обрабатываются так, как если бы они были изменчивыми. Энергозависимая запись имеет семантику освобождения блокировки, что означает, что все предыдущие записи должны быть зафиксированы до текущей записи.
Однако спецификация ECMA имеет более слабую модель памяти. Таким образом, теоретически возможно, что Mono или даже будущая версия .NET Framework может начать демонстрировать ошибочное поведение.
Итак, я говорю, что очень маловероятно, что устранение барьеров № 1 и № 2 окажет какое-либо влияние на поведение программы. Это, конечно, не гарантия, а наблюдение, основанное только на текущей реализации CLR.
Удаление барьеров № 3 и № 4 определенно окажет влияние. Это на самом деле довольно легко воспроизвести. Ну, не этот пример сам по себе, но следующий код является одной из наиболее известных демонстраций. Он должен быть скомпилирован с использованием сборки Release и запущен вне отладчика. Баг в том, что программа не заканчивается. Вы можете исправить ошибку, поместив вызов на Thread.MemoryBarrier
внутри цикла while
или пометив stop
как volatile
.
class Program
{
static bool stop = false;
public static void Main(string[] args)
{
var t = new Thread(() =>
{
Console.WriteLine("thread begin");
bool toggle = false;
while (!stop)
{
toggle = !toggle;
}
Console.WriteLine("thread end");
});
t.Start();
Thread.Sleep(1000);
stop = true;
Console.WriteLine("stop = true");
Console.WriteLine("waiting...");
t.Join();
}
}
Причина, по которой некоторые ошибки в потоке трудно воспроизвести, заключается в том, что та же тактика, которую вы используете для симуляции чередования потоков, может фактически исправить ошибку. Thread.Sleep
является наиболее заметным примером, потому что он создает барьеры памяти. Вы можете убедиться в этом, поместив вызов внутри цикла while
и заметив, что ошибка исчезла.
Вы можете увидеть мой ответ здесь для другого анализа примера из книги, которую вы цитировали.