Я понимаю, что поток может кэшировать значение и ignore changes made on another thread, но мне интересно об этом. Возможно ли, чтобы поток изменил кешированное значение, которое никогда не покидает его кеш и поэтому никогда не видимо для других потоков?Когда я могу гарантировать, что значение, измененное в одном потоке, видно на другие темы?
Например, может этот код печать «Флаг правда» потому что нить a
никогда не видит изменений, что нить b
делает на flag
? (Я не могу сделать это сделать, но я не могу доказать, что это, или некоторые вариации этого, не будет.)
var flag = true;
var a = new Thread(() => {
Thread.Sleep(200);
Console.WriteLine($"Flag is {flag}");
});
var b = new Thread(() => {
flag = false;
while (true) {
// Do something to avoid a memory barrier
}
});
a.Start();
b.Start();
a.Join();
Я могу себе представить, что на резьбе b
flag
может кэшировать в Регистр CPU, где он затем устанавливается в false
, и когда b
входит в цикл while
, он никогда не получает шанс (или никогда не обращает на себя внимания) записать значение flag
обратно в память, поэтому a
всегда видит flag
как истинный.
Из генераторов барьера памяти, перечисленных в this answer, мне кажется, что это возможно в теории. Я прав? Я не смог продемонстрировать это на практике. Может ли кто-нибудь придумать пример, который делает?
http://stackoverflow.com/questions/6581848/memory-barrier-generators –
@MatthewWatson, спасибо, эта ссылка отвечает на вопрос, который я изначально задавал, но не то, что я пытаюсь выяснить. Я отредактировал вопрос, чтобы отразить это. Я действительно преследую ошибку, которая может быть объяснена тем, что я описываю выше, но я хочу знать, насколько я прав в своих рассуждениях и насколько это возможно на самом деле. – eoinmullan
ОК, я снова открыл этот вопрос, теперь он был изменен. –