Почему не там никакие параллельные наборы в C#?

Я пытаюсь получить обзор теории потокобезопасности позади наборов в C#.

Почему не там никакие параллельные наборы, поскольку существует в Java? (документы Java). Некоторые наборы кажутся ориентированными на многопотоковое исполнение, но мне не ясно, относительно чего положение, например:

  • составные операции,
  • безопасность использования итераторов,
  • операции записи

Я не хочу изобретать велосипед! (Я не гуру многопоточности и определенно не недооцениваю, как трудно это было бы так или иначе).

Я надеюсь, что сообщество может помочь.

15
задан Andrew 22 December 2009 в 13:57
поделиться

3 ответа

.NET до сих пор имела относительно "низкоуровневую" поддержку параллелизма, но .NET 4.0 вводит пространство имен System.Collections.Concurrent , которое содержит различные коллекции, которые являются безопасными и

Ответ Эндрю, конечно же, совершенно верен с точки зрения того, как работать с коллекциями до .NET 4.0 - и для большинства использования я бы просто заблокировал надлежащим образом при доступе к «нормальной» общей коллекции. Однако параллельные коллекции упрощают использование очереди производителя / потребителя и т. Д.

29
ответ дан 1 December 2019 в 00:11
поделиться

C # предлагает несколько способов работы с коллекциями в нескольких потоках. Для хорошего описания этих методов я бы рекомендовал начать с Коллекции и синхронизация (безопасность потоков) :

По умолчанию классы Коллекций вообще не потокобезопасный. Множественный читатели могут прочитать сборник с уверенность; однако любые модификации в коллекцию производит undefined результаты для всех потоков, которые обращаются сборник, включая читателя потоков.

Коллекции классов можно сделать потоками. безопасно использовать любое из следующих методы:

  • Создайте потокобезопасную оболочку с помощью метода Synchronized и доступ к коллекции исключительно через эту оболочку.
  • Если класс не имеет синхронизированного метода, наследовать от class и реализовать синхронизированный метод с использованием свойства SyncRoot.
  • Используйте механизм блокировки, такой как оператор блокировки в C # (SyncLock в Visual Basic) на SyncRoot свойство при доступе к сборник.
19
ответ дан 1 December 2019 в 00:11
поделиться

Как упомянул Джон Скит, теперь в пространстве имен System.Collections.Concurrent в .NET 4. теперь есть «потокобезопасные» коллекции.

Одна из причин отсутствия параллельных коллекций (в По крайней мере, я предполагаю) в предыдущих версиях .NET Framework, что очень сложно гарантировать безопасность потоков даже при параллельной коллекции.

(Это не совсем так, поскольку некоторые коллекции предлагают метод Synchronized для возврата поточно-безопасной коллекции из небезопасной для потоков коллекции, поэтому есть несколько поточно-безопасных коллекций ...)

Например, предположим, что у одной есть поток безопасный словарь - если кто-то хочет вставить только в том случае, если ключ не существует, нужно сначала запросить коллекцию, чтобы узнать, существует ли ключ, затем можно будет выполнить вставку, если ключ не существует. Однако эти две операции не являются потокобезопасными, между запросом ContainsKey и операцией добавления другой поток мог выполнить вставку этого ключа, поэтому возникло состояние гонки.

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

6
ответ дан 1 December 2019 в 00:11
поделиться