2010-05-09 3 views
12

ли иметь 2 разные темы:
безопасности потоков в массивах C#

  • одно чтение из C# массива (например, от первого места),
  • и еще один записи в том же C# массив, но к в другом месте (например, до последнего места)

является потокобезопасным или нет?
(И я имею в виду здесь без блокировки чтения или записи)

ответ

8

Этот конкретный случай безопасен, да.

Чтение и запись в разные части массива не мешает другим операциям.

Однако чтение и запись в том же месте могут дать вам проблемы в зависимости от типа элемента и размера элементов.

+1

Пока эти элементы находятся в отдельных словах CPU – Stewart

+0

+1 Никогда не думал, что это будет потокобезопасным, но я понимаю, почему это так. Благодаря! –

+0

Важно учитывать при использовании алгоритмов блокировки, что то, что вы считаете «одной и той же позицией», не совпадает с тем, что CPU (ы) считают одной и той же позицией. Представление CPU о памяти сильно отличается от языков представления, таких как C, где мы занимаем адреса байтов. На некоторых архитектурах процессора (особенно ARM, Power) на некоторых типах данных даже это может быть небезопасно. – Stewart

5

Краткая история: Да. До тех пор, пока он находится в двух разных местах, это безопасная операция.

Был discussion about this некоторое время назад, у него есть полезная информация, если вам интересно.

+0

+1 Никогда не думал, что это будет потокобезопасно, но я понимаю, почему это так. Благодаря! –

7

Я не уверен, что это гарантировано будет безопасным. Представьте, что у вас есть байт []. Эти байты плотно упакованы в память. Теперь, если вы измените эти байты, компилятор может объединить некоторые из операций записи для выполнения операций чтения с записью (32 бит) размера. Например, на некоторых процессорах ARM это единственный вид команды модификации памяти, которую имеет компилятор. Это особенно удобно, если вы изменяете более одного байта за раз. Процессор может сделать то же самое. Он также может переупорядочить материал, не зная об этом. Перед лицом такой оптимизации можно, чтобы поток, читающий смежную память, мог видеть частичные модификации. Вы не видите такого эффекта, потому что распределитель кучи хорош для вас и всегда дает вам память, которая по крайней мере выравнивается по слову.

+1

+1: По-моему, это лучший ответ. Всегда лучше скептически относиться к идиомам, зависящим от блокировки. Я могу думать обо всех проблемах с защитой памяти, которые могут вызвать проблемы, даже если потоки работают с разными позициями в массиве. Просто просто недостаточно информации, предоставленной в вопросе, чтобы дать окончательный ответ. –