2013-06-27 3 views
2

Эта строка кода выполняется в Parallel.For (... row => {code});Является ли это «двойной + =» потоком безопасным?

mechanismScores[row] += cellValue; 

Значения массива и CellValue оба типа двойного. Является ли эта нить безопасной или мне нужно что-то делать ...

Interlocked.CompareExchange(ref mechanismScores[row], 
    mechanismScores[row] + cellValue, mechanismScores[row]); 

или еще одно решение?

+0

Ни один из них не является безопасным. Два потока могут считывать одно и то же значение и увеличивать его. – SLaks

+0

Кроме того, какой тип 'mechanScores'? – SLaks

+1

'Interlocked.CompareExchange (ref механизмScores [строка], механизмScores [строка] + cellValue, механизмScores [строка])' небезопасно: вызов функции может оценивать два разных значения для 'mechanScores [row]' для второго и третьего аргументы, если другой поток изменял его одновременно. –

ответ

0

Какой бы тип механизма не был, это похоже на то, что это объект, поэтому сделает простой замок (механизмScores). Если внутри цикла то же значение может быть изменено в разных контекстах, то оно не является потокобезопасным.

+0

, но имейте в виду, что механизм блокировкиScores (блокировка (механизмScores)), скорее всего, удалит все преимущества использования parallel.foreach в первую очередь. – Marco

+0

Я понимаю, что я потеряю преимущество Parallel ... –

+2

Это не тот вопрос, который задает вопрос. – svick

6

Если у вас есть параллельный цикл, в котором каждая итерация обращается к другому элементу в массиве, и никакой другой код не обращается к массиву в одно и то же время, тогда ваш код является потокобезопасным.

Если две итерации имеют доступ к одному и тому же индексу в массиве, вам понадобится какая-то синхронизация, либо используя lock, либо правильно используя Interlocked.CompareExchange() (как указал Майкл Бурр, ваш пример небезопасен).

Смежные вопросы