<vector> безопасен для чтения / записи в разных местах? - PullRequest
12 голосов
/ 23 июня 2011

это вопрос для начинающих, я думаю, но я не смог найти ответ на этот конкретный вопрос:

У меня есть стандартный (c ++) вектор v размера 10 и типа int.

Безопасно ли, чтобы поток изменял все четные позиции (v.at (0) = x; v.at (2) = y; и т. Д.) и другой поток изменяет все значения для нечетных позиций (v.at (1) = a; v.at (3) = b; и т. д.) одновременно?

так, без изменения размера, без push_back () и т. Д. В течение времени жизни этих двух потоков.

если это небезопасно, будет ли использование массива лучшим способом сделать это?

спасибо за вашу помощь.

Ответы [ 5 ]

11 голосов
/ 23 июня 2011

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

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

7 голосов
/ 23 июня 2011

Из MSDN: Потокобезопасность в стандартной библиотеке C ++

Для операций чтения с одним и тем же объектом объект является поточно-ориентированным для чтения:

  • Из одного потока в тот момент, когда в других потоках нет авторов.
  • Из многих потоков в то время, когда нет писателей в других потоках.

Для записи в один и тот же объект объект является поточно-ориентированным для записи из одного потока, когда нет читателей в других потоках

Для чтения в разные объекты одного и того же класса, объектПотокобезопасен для чтения:

  • Из одного потока за раз.
  • Из одного потока в тот момент, когда нет писателей в других потоках.
  • Из множества тем одновременно.
  • Из многих потоков в то время, когда нет писателей в других потоках.

Для записи в различные объекты одного и того же класса объект является потокобезопасным для записи:

  • Из одного потока, когда в других потоках нет читателей.
  • Из множества тем.

Итак, из вышесказанного, Теоретически, НЕТ, это не будет потокобезопасным .

5 голосов
/ 23 июня 2011

Это зависит от машины. Если у вас vector<char>, процессор может не загрузить v [i] и v [i + 1] в отдельных словах. У вас могут быть проблемы с согласованностью кэша.

И компилятор, и процессор могут переупорядочивать инструкции, что может нарушить вашу программу, даже если вышеприведенное не применимо. Вот почему C ++ 0x имеет модель памяти.

5 голосов
/ 23 июня 2011

Теоретически: №

Практически: да (в зависимости от того, как реализованы все известные STL)

4 голосов
/ 23 июня 2011

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

...