Комментарии 18
Был бы рад, если бы мне указали неясные или неточные места в статье. В свою очередь постараюсь улучшить статью в соответствии с высказанными пожеланиями.
Есть мелкая неточность
->Если инструкции программы выполнялись бы именно в том порядке, в котором они определены, то обе строки всегда оказывались бы равными “а”.
Обе строчки практически никогда не будут равны «a». Корректно написать — хотя бы одна строчка всегда будет «а».
Если в следущей строчке заменить && на ||, то на однопроцессорной машине всегда будет 100 выводить.
Но тем не менее, пример показателен, в 0.0007% случаев обе операции чтения происходят раньше операций записи.
->Если инструкции программы выполнялись бы именно в том порядке, в котором они определены, то обе строки всегда оказывались бы равными “а”.
Обе строчки практически никогда не будут равны «a». Корректно написать — хотя бы одна строчка всегда будет «а».
Если в следущей строчке заменить && на ||, то на однопроцессорной машине всегда будет 100 выводить.
if (_firstString == null && _secondString == null)
Но тем не менее, пример показателен, в 0.0007% случаев обе операции чтения происходят раньше операций записи.
Отлличая грамотная статья
Сколько же нервов можно потратить, если не знать такие вещи при разработке многопоточных приложений! У одного Албахари написано в целом понятно, не вдаваясь в подробности про барьеры памяти и их тонкости, а вы же копнули гораздо глубже. Обычно таких статей очень не хватает, и частенько от недопонимания причин неработоспособности проблемного места людьми с горя вешается
, хорошо еще, если не на большой участок кода.
В общем, спасибо, в закладки =)
lock (monitor)
{
//... а у нас тут все хорошо =)
}
, хорошо еще, если не на большой участок кода.
В общем, спасибо, в закладки =)
БОльшое спасибо за опдборку ссылок давно пытался найти источники по многопоточности в .NET. Но вот банальные запросы вроде ".net memory model" ничего дельного на на поверхность не выносили :(
Я бы посоветовал прочесть «Concurrent Programming on Windows». По статьям в интернете на мой взгляд разбираться сложнее. Проверил на собственном опыте:)
Отличная техническая статья в топе? Глазам своим не верю!
Без тени желтизны, политики и холивара? Фантастика!
Ах, из песочницы… М-да, что-то я расчувствовался, простите.
P.S. Добро пожаловать, rumatavz. (Или с возвращением? :)
Без тени желтизны, политики и холивара? Фантастика!
Ах, из песочницы… М-да, что-то я расчувствовался, простите.
P.S. Добро пожаловать, rumatavz. (Или с возвращением? :)
Мне кажется, что в секции «Перестановка инструкций» некоторая неточность. Если оба метода запускаются кем-то из разных потоков, то не нужен Task. Если же Foo запускает Bar через Task, то для «одновременности» нужно вызвать task.Start(); до присвоения полей.
Немного не понял вот это — «На большинстве платформ… все записи и чтения являются volatile write и volatile read». Тогда почему все же необходимо ключевое слово volatile?
Немного не понял вот это — «На большинстве платформ… все записи и чтения являются volatile write и volatile read». Тогда почему все же необходимо ключевое слово volatile?
Спасибо, исправил.
Во первых, на большинстве платформ — это не на всех. Отлавливать потом баги, появляющиеся только в продакшене не очень весело. Во вторых, volatile гарантирует отсутствие оптимизаций компилятора, а это касается любой платформы.
Во первых, на большинстве платформ — это не на всех. Отлавливать потом баги, появляющиеся только в продакшене не очень весело. Во вторых, volatile гарантирует отсутствие оптимизаций компилятора, а это касается любой платформы.
Насколько я понимаю, читая www.albahari.com/threading, чтение и запись volatile — данных также могут переставляться местами?
спасибо огромное! в закладки!
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Барьеры памяти и неблокирующая синхронизация в .NET