В c ++, является ли векторный поток безопасным при записи из одного потока и чтения из другого? [Дубликат]

Также, если вы используете сторонние библиотеки, убедитесь, что у вас есть правильные 32/64 битные файлы

31
задан fat 5 November 2013 в 11:29
поделиться

3 ответа

У меня есть несколько потоков, одновременно вызывающих push_back () для общего объекта std :: vector. ... Я надеюсь найти существующие поточно-безопасные решения для вектора.

Взгляните на concurrent_vector в TBB Intel . Строго говоря, он сильно отличается от std::vector внутренне и не полностью совместим с API, но все же может быть подходящим. Вы можете найти некоторые детали своего дизайна и функциональности в блогах разработчиков TBB .

8
ответ дан Alexey Kukanov 5 September 2018 в 07:28
поделиться

Стандарт C ++ обеспечивает определенные гарантии потоковой передачи для всех классов стандартной библиотеки C ++. Эти гарантии могут быть не такими, какие вы ожидали бы от них, но для всех стандартных классов библиотеки C ++ выполняются определенные гарантии безопасности потоков. Убедитесь, что вы прочитали гарантии, хотя, поскольку гарантии на резьбу стандартных контейнеров C ++ обычно не совпадают с тем, что вы хотели бы, чтобы они были. Для некоторых классов разные, как правило, более высокие гарантии, и ответ ниже конкретно применяется к контейнерам. Контейнеры по существу имеют следующие гарантии безопасности потоков:

  1. могут быть несколько одновременных считывателей одного и того же контейнера
  2. , если есть один писатель, не должно быть больше писателей и нет читателей

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

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

Гарантии и требования приведены в 17.6.4.10 [res.on.objects], пункт 1:

Поведение программы не определено, если вызовы стандартных библиотечных функций из разных потоков могут привести к гонке данных. Условия, при которых это может произойти, указаны в 17.6.5.9. [Примечание. Изменение объекта стандартного типа библиотеки, разделяемого между потоками, определяет неопределенное поведение, если объекты этого типа явно не определены как разделяемые без расчётов данных или пользователь поставляет механизм блокировки. -Endnote]

... и 17.6.5.9 [res.on.data.races]. В этом разделе по существу подробно описывается более неофициальное описание в не.

48
ответ дан Dietmar Kühl 5 September 2018 в 07:28
поделиться

У меня есть несколько потоков, одновременно вызывающих push_back () на общем объекте std :: vector. Является ли std :: vector thread safe?

Это небезопасно.

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

Да.

Я хочу избежать выполнения дополнительной операции «блокировки и освобождения», потому что я являюсь пользователем библиотеки, а не разработчиком библиотеки. Я надеюсь найти существующие поточно-безопасные решения для вектора.

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

Как насчет boost :: vector, который был недавно введен с boost 1.48.0 onward ,

Состояние документов:

//! boost::container::vector is similar to std::vector but it's compatible
//! with shared memory and memory mapped files.
26
ответ дан justin 5 September 2018 в 07:28
поделиться
Другие вопросы по тегам:

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