Работает ли безопасная публикация и безопасность инициализации в .NET? - PullRequest
2 голосов
/ 03 января 2012

Книга «Параллелизм Java на практике» оказалась для меня отличным руководством по написанию многопоточного кода для Java.Мне интересно, в какой степени общие принципы, описанные в книге, применимы к .Net.Я не заинтересован в развертывании своего собственного кода без блокировки - я просто хочу использовать надежные, понятные методы и использовать существующие синхронизированные и параллельные API.В этой степени ключевые выводы из книги для меня были:

  1. Блокировка - изменения состояния, сделанные внутри блокировки в одном потоке, видны всем другим потокам внутри блокировок того же объекта.Без сомнения, это работает в .NET и будет достаточно для написания поточно-ориентированных программ, но это приведет к ненужной блокировке, если мы не сможем полагаться на следующие механизмы.
  2. Безопасная публикация - последнее состояние эффективно неизменяемого объекта (Объект, который не изменяется после публикации), виден всем потокам при условии выполнения одного из следующих действий.Обратите внимание, что просмотр самого последнего состояния ссылки на объект не обязательно совпадает с просмотром самого последнего состояния самого объекта - в Java безопасная публикация работает из-за транзитивного характера отношения «происходит до».
    • Доступ к его ссылкам синхронизируется через блокировки во всех потоках
    • На него ссылается переменная с переменным значением
    • Публикуется из синхронизированной или одновременной коллекции.
  3. Последнее состояние правильно построенных неизменяемых объектов с только конечными полями (только для чтения в .NET) является потокобезопасным независимо от того, как они публикуются.

IБудем надеяться, что все это работает, в противном случае это делает жизнь излишне трудной, но из того, что я подготовил, модель для .Net (по крайней мере, как указано) довольно слабая.Кто-нибудь пытался построить модель «до и после» для .NET?Я думаю, что это та область, которую нужно решать в .Net.Насколько я знаю, не существует эквивалентной книги для .Net, которая могла бы дать тот же «уровень комфорта» - кажется, что по крайней мере отчасти проблема заключается в отсутствии четко определенной модели памяти для .NET.

Ответы [ 2 ]

3 голосов
/ 23 января 2012

Общие понятия одинаковы.Однако необходимо учитывать различия между моделью памяти Java и .NET.Обычно это включает в себя использование функций Interlocked Java ), VolatileRead / VolatileWrite или явный барьер памяти .

Для .NET указаны две модели памяти.Модель слабой памяти, указанная в Разделе 12, Раздел I стандарта .NET Framework ECMA. Более сильная модель памяти фактически реализуется средой выполнения .NET Framework.Альтернативное определение описывается Джо Даффи .Один практический случай, когда модель памяти .NET отличается от Java, описан в блоге IKVM.NET .

По поводу ваших точек зрения:

  1. Блокировка работает так же, как в Java.

  2. Безопасная публикация - первые два сценария (блокировки и volatile ) работают идентично аналогам Java.

    Синхронизированные коллекции в .NET устарели, но они внутренне используют блокировку, поэтому они работают точно так же, как если бы доступ был заблокирован.

    Параллельные коллекции добавлены как частьВнутри .NET 3.5 используются методы без блокировок, поэтому они должны быть согласованы между различными потоками памяти.Я не уверен, что они согласованы с памятью.

  3. Неизменяемый объект по определению является потокобезопасным.Как только вы создадите неизменный объект, он больше не может быть изменен.Созданный им поток является единственным потоком, который может иметь свою копию в кэше.Как только вы опубликуете его, все остальные потоки получат актуальную копию, и эта копия гарантированно не изменится.Таким образом, единственным больным вопросом является сама публикация.Вам все еще нужно заботиться о безопасной публикации, чтобы не создавать два экземпляра неизменяемого объекта, но каждый из этих экземпляров будет поточно-ориентированным при доступе из любого потока.
1 голос
/ 20 января 2012

Я не пытался построить модель «до того, как это произошло», но я реализовал структуры данных без блокировки в .Net (кольцевой буфер без блокировки, совсем недавно).

Ссылки, опубликованные из переменных переменныхгарантированно являются «безопасными», ключевое слово volatile в .Net вызывает прямое считывание этой ссылки из памяти и вынуждает любое изменение этой ссылки выполнять прямую запись в память.

Сравнение двухОднако изменчивые переменные могут привести к несвоевременным выводам.В кольцевом буфере без блокировки, который я написал, это не было проблемой.Метод enqueue иногда считал, что буфер был заполнен, когда это был один застенчивый элемент (удаление очереди происходит так же, как я сравниваю свои изменчивые указатели головы и хвоста);метод dequeue иногда думал, что буфер был пуст по той же причине.Однако в моем случае данные не были потеряны.

Таким образом, чтобы ответить на ваш общий вопрос, внедрение структур данных без блокировки в .Net, безусловно, возможно, я это сделал и без особой боли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...