https://msdn.microsoft.com/en-us/magazine/jj883956.aspx
Рассмотрим шаблон циклы опроса:
private bool _flag = true; public void Run() { // Set _flag to false on another thread new Thread(() => { _flag = false; }).Start(); // Poll the _flag field until it is set to false while (_flag) ; // The loop might never terminate! }
В этом случае компилятор.NET 4.5 JIT может переписать цикл следующим образом:
if (_flag) { while (true); }
В однопоточном случае это преобразование полностью легально и, в общем, подъем считывания из цикла является отличной оптимизацией. Однако, если для параметра _flag установлено значение false в другом потоке, оптимизация может привести к зависанию.
Обратите внимание, что если поле _flag было изменчивым, компилятор JIT не мог бы вытащить считывание из цикла. (См. Раздел "Опрос циклы" в декабрьской статье для более подробного объяснения этого шаблона.)
Будет ли компилятор JIT по-прежнему оптимизировать код, как показано выше, если я заблокирую _flag
или просто сделаю его volatile
остановив оптимизацию?
Эрик Липперт должен сказать об изменчивости:
Честно говоря, я отговариваю вас от когда-либо создающего неспокойное поле. Неустойчивые поля являются признаком того, что вы делаете что-то совершенно безумное: вы пытаетесь читать и писать одно и то же значение на двух разных потоках, не помещая блокировку на место. Замки гарантируют, что память, считываемая или измененная внутри замка, будет последовательной, блокировки гарантируют, что только один поток обращается к заданному блоку памяти за раз и так далее. Количество ситуаций, в которых блокировка слишком медленная, очень мала, и вероятность того, что вы собираетесь получить код неправильно, потому что вы не понимаете, что точная модель памяти очень велика. Я не пытаюсь написать код с низким уровнем блокировки, за исключением самых простых операций блокировки. Я оставляю использование "изменчивых" для реальных экспертов.
Подводя итог: Кто гарантирует, что упомянутая выше оптимизация не разрушит мой код? Только volatile
? Также оператор lock
? Или что-то другое?
Как Эрик Липперт отговаривает вас от использования volatile
должно быть что-то еще?
Downvoters: Я ценю каждую обратную связь на вопрос. Особенно, если вы отказались от этого, я хотел бы услышать, почему вы думаете, что это плохой вопрос.
Переменная bool не является примитивом синхронизации потоков: вопрос подразумевается как общий вопрос. Когда компилятор не сделает оптимизацию?
Dupilcate: Этот вопрос явно посвящен оптимизации. В том, что вы связали, не упоминается оптимизация.