Ориентированный на многопотоковое исполнение Векторный класс для C++

Какова Ваша кодовая база? Java или C++?

alt text

eUML2 для Java является мощным средством моделирования UML, разработанным для разработчика Java в Eclipse. Свободный выпуск может использоваться для коммерческого использования. Это поддерживает следующие функции:

  • CVS и Поддержка Команды
  • Разработанный для крупного проекта с несколькими и настраиваемыми образцовыми представлениями
  • Helios Compliant
  • синхронизация кода/модели В реальном времени
  • UML2.1 совместимый и поддержка OMG XMI
  • JDK 1.4 и 1,5 поддержки
  • коммерческий выпуск обеспечивает:

  • Усовершенствованная обратная разработка

  • Мощная истинная зависимость анализируют инструменты
  • Профиль UML и инструменты MDD
  • Database
  • поддержка шаблона Customizable

14
задан ras2124 8 July 2009 в 17:39
поделиться

5 ответов

Это сложно из-за алгоритмов.

Предположим, вы обернули вектор так, что все его функции-члены сериализованы с использованием мьютекса, как синхронизированные методы Java. Тогда одновременные вызовы std :: remove этого вектора по-прежнему будут небезопасными, потому что они полагаются на просмотр вектора и изменение его в зависимости от того, что они видят.

Таким образом, ваш LockingVector должен будет Специализируйте каждый шаблон на стандартных алгоритмах, чтобы заблокировать все это. Но тогда другие алгоритмы, такие как std :: remove_if , будут вызывать пользовательский код под блокировкой. Выполнение этого незаметно за кулисами - это рецепт блокировки инверсии, как только кто-то начинает создавать векторы объектов, которые сами внутренне блокируют все свои методы.

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

template <typename T>
class LockedVector {
    private:
    SomeKindOfLock lock;
    std::vector<T> vec;
};

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

8
ответ дан 1 December 2019 в 13:33
поделиться

Вы можете проверить TBB (например, concurrent_vector ). Я никогда не использовал его, хотя, честно говоря, мне легче разместить объекты защиты области видимости вокруг доступа (особенно если вектор правильно инкапсулирован).

6
ответ дан 1 December 2019 в 13:33
поделиться

Я думаю, вам будет намного проще продолжать использовать std :: vector, но для защиты параллельного доступа с помощью какого-либо мьютекса или другого объекта синхронизации операционной системы. Вы также определенно захотите использовать RAII, если используете мьютекс.

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

Как объясняет Скотт Мейерс в эффективной книге STL, с помощью поточно-безопасного контейнера можно ожидать что:

  • Множественные чтения безопасны
  • Множественные записи в разные контейнеры безопасны.

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

1
ответ дан 1 December 2019 в 13:33
поделиться

Я забыл, кто это обсуждал, но одна стратегия создания поточно-безопасного контейнера следующая:

  1. Все общедоступные методы вашего класса должны блокировать вектор , и должен возвращать логическое значение for, если им это удалось (а может и не получиться!). Поэтому вместо использования f = myvec [i] используйте if (myvec.tryGet (i, & f)) {...} и соответствующим образом реализуйте класс.
  2. Do не предоставляют метод подсчета. Пользователи должны использовать итераторы для обхода вектора.

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

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

Второе средство предоставления «поточно-ориентированных» контейнеров заключается в создании неизменяемых контейнеров (каждый метод возвращает новый контейнер. Это определенно обсуждалось Эриком Липпертом . Это C #, но в основном легко переводится в код C ++. Вам все равно придется заблокировать контейнер, когда вы используй это, но все пугающие проблемы, связанные с переполнением буфера, когда итераторы ломаются и еще много чего не происходит. Реализация неизменяемого контейнера, вероятно, относительно вторая натура для тех, кто имеет опыт функционального программирования.

0
ответ дан 1 December 2019 в 13:33
поделиться
Другие вопросы по тегам:

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