Действительно ли несколько потоков могут получить доступ к вектору в различных местах?

Позволяет говорят, что у меня есть вектор интервала, который я предварительно заполнил 100 элементами со значением 0.

Затем я создаю 2 потока и говорю первому потоку заполнять элементы от 0 до 49 с числами, затем говорить потоку 2 заполнять элементы 50 - 99 числами. Это может быть сделано? Иначе, каков лучший способ достигнуть этого?

Спасибо

11
задан JSBձոգչ 1 June 2010 в 16:09
поделиться

7 ответов

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

5
ответ дан 3 December 2019 в 09:40
поделиться

Тот факт, что « вектор не является потокобезопасным», ничего не значит. С этим нет проблем.

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

И, конечно же, поскольку вы хотите, чтобы оба потока работали с одним и тем же вектором, они должны получать его откуда-то по указателю / ссылке, а не по значению.

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

Проще говоря - нет проблем с доступом к массиву из разных потоков. Доступ к одному и тому же элементу из другого потока похож на доступ к одной переменной из другого потока - те же меры предосторожности / последствия.

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

2
ответ дан 3 December 2019 в 09:40
поделиться

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

4
ответ дан 3 December 2019 в 09:40
поделиться

vector не является потокобезопасным. Вам нужно охранять вектор между потоками. В вашем случае это зависит от реализации vector. Если к внутренним данным вектора обращаются\модифицированные из разных потоков, то это зависит только от имплантов вектора.

0
ответ дан 3 December 2019 в 09:40
поделиться

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

1
ответ дан 3 December 2019 в 09:40
поделиться

С массивами это точно можно сделать (потоки не обращаются к одной и той же области памяти); но, как уже отмечалось, если вы используете класс std::vector, результат может зависеть от того, как он реализован. Действительно, я не вижу, как реализация [] в классе vector может быть потокобезопасной (при условии, что потоки пытаются получить доступ к разным "индексам"), но это может быть так. Решение таково: придерживаться использования массива или контролировать доступ к вектору с помощью семафора или чего-то подобного.

0
ответ дан 3 December 2019 в 09:40
поделиться

То, что вы описываете, вполне возможно, и слова должны быть хорошими.

Обратите внимание, однако, что потоки должны будут работать с std :: vector * , то есть указателем на исходный вектор --- и вам, вероятно, следует разместить вектор в куче, а не чем стек. Если вы передадите вектор напрямую, будет вызван конструктор копирования, который создаст отдельную копию данных в каждом потоке.

Есть также множество более тонких способов ошибиться, как всегда в многопоточном программировании. Но в принципе то, что вы описали, будет работать хорошо.

-1
ответ дан 3 December 2019 в 09:40
поделиться