Массивы действительно ли C# ориентированы на многопотоковое исполнение?

Под Инструментами> Предпочтения> Базы данных там являются третьим лицом путь драйвера JDBC, который должен быть установкой. Как только путь драйвера является установкой, отдельная вкладка 'MySQL' должна появиться на Новом диалоговом окне Соединений.

Примечание: Это - тот же jdbc коннектор, который доступен как загрузка JAR с веб-сайта MySQL.

51
задан Thomas Ayoub 1 April 2015 в 23:20
поделиться

4 ответа

Я считаю, что если каждый поток работает только с отдельной частью массива, все будет хорошо. Если вы собираетесь совместно использовать данные (то есть передавать их между потоками), тогда вам понадобится какой-то барьер памяти, чтобы избежать проблем с моделью памяти.

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

РЕДАКТИРОВАТЬ: Ваш пример кода безопасен. Два потока никогда не обращаются к одному и тому же элементу - это как если бы каждый из них имел отдельные переменные. Однако само по себе это не приносит пользы. В какой-то момент обычно потоки захотят поделиться своим состоянием - один поток захочет прочитать то, что написал другой. В противном случае им нет смысла писать в общий массив, а не в свои собственные частные переменные. Это момент, в котором вам нужно быть осторожным - координация между потоками.

44
ответ дан 7 November 2019 в 10:11
поделиться

В документации MSDN по массивам говорится:

Public static (Shared in Visual Базовый) члены этого типа потокобезопасны. Члены экземпляра не являются гарантированно поточно-ориентированная.

Эта реализация не предоставляет синхронизированная (потокобезопасная) оболочка для массив; однако .NET Framework классы на основе Array предоставляют свои собственная синхронизированная версия сбор с помощью SyncRoot свойство.

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

Так что нет, они не потокобезопасны.

25
ответ дан 7 November 2019 в 10:11
поделиться

Обычно, когда о коллекции говорят, что она «не потокобезопасная», это означает, что одновременный доступ может потерпеть неудачу изнутри (например, небезопасно читать первый элемент List , пока другой поток добавляет элемент в конце списка: List может изменить размер базового массива, и доступ для чтения может перейти к новому массиву до того, как в него будут скопированы данные).

Такие ошибки невозможны с массивами, потому что массивы фиксированы -размеры и не имеют таких «структурных изменений». Массив с тремя элементами не более или менее потокобезопасен, чем три переменные.

В спецификации C # об этом ничего не говорится; но это ясно, если вы знаете IL и читаете спецификацию CLI - вы можете получить управляемую ссылку (например, те, которые используются для параметров C # "ref") на элемент внутри массива, а затем выполнять как нормальную, так и изменчивую загрузку и сохранение в него. Спецификация CLI описывает гарантии безопасности потоков для таких загрузок и хранилищ (например, атомарность для элементов <= 32 бит)

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

14
ответ дан 7 November 2019 в 10:11
поделиться

Приведенный вами пример очень похож на способ, которым используются собственные параллельные расширения Microsoft в C # 4.0 работают.

Этот цикл for:

for (int i = 0; i < 100; i++) { 
  a[i] = a[i]*a[i]; 
}

становится

Parallel.For(0, 100, delegate(int i) { 
  a[i] = a[i]*a[i]; 
});

Итак, да, ваш пример должен быть в порядке. Вот более старая запись в блоге о новой поддержке параллельного интерфейса в C #.

5
ответ дан 7 November 2019 в 10:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: