Является ли C ++ STL поточно-ориентированным для отдельных контейнеров (с использованием реализации STLport)? - PullRequest
11 голосов
/ 10 декабря 2010

Я использую Android 2.2, который поставляется с версией STLport.По некоторым причинам это было настроено, чтобы быть безопасным от потока.Это было сделано с помощью #define _NOTHREADS в заголовочном файле конфигурации.

Когда я сконструировал и инициализировал отдельные неиспользуемые контейнеры (например, строки) из разных потоков, я получил повреждение памяти.

С _NOTHREADS похоже, что какой-то низкоуровневый код в STL внутри allocator.cpp не выполняет надлежащую блокировку.Похоже, что C не обеспечивает безопасность потоков для malloc.

Кто-нибудь знает, почему STL может быть построен с _NOTHREADS по умолчанию на Android?Отключая это, я задаюсь вопросом, может ли быть побочный эффект.Одна вещь, о которой я могу думать, это слегка ухудшенная производительность, но я не вижу большого выбора, учитывая, что я использую много потоков.

Ответы [ 5 ]

5 голосов
/ 10 декабря 2010

SGI STL

SGI STL - это бабушка всех других реализаций STL.

См. документы SGI STL .

Реализация SGI STL потокобезопасен только в том смысле, что одновременный доступ к отчетливым контейнеры безопасны и одновременны чтение доступа к общим контейнерам безопасны Если несколько потоков обращаются к один контейнер и хотя бы один Поток может потенциально написать, тогда Пользователь несет ответственность за обеспечение взаимное исключение между потоками во время доступа к контейнеру.

G ++

libstdc ++ документы

В настоящее время мы используем определение безопасности потоков SGI STL.

STLPort

STLPort документы

Пожалуйста, обратитесь к сайту SGI для подробного документ по безопасности ниток. основной Очки:

  • одновременный доступ на чтение к одному и тому же контейнеру из темы безопасны;
  • одновременный доступ к отдельным контейнерам (не разделяется между темы) безопасен;
  • пользователь должен обеспечить синхронизацию для всех обращений, если любой поток может изменить общий контейнер.
2 голосов
/ 10 декабря 2010

Общая информация о стандарте C ++

Текущий стандарт C ++ вообще не решает проблемы параллелизма, поэтому, по крайней мере, на данный момент нет требований, применимых ко всем реализациям.

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

1 голос
/ 10 декабря 2010

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

0 голосов
/ 10 декабря 2010

Когда вы используете, например, std :: string или аналогичные объекты и изменяя их из разных потоков, вы разделяете один и тот же объект между потоками. Чтобы сделать любую функцию-член, которую вы можете вызывать с повторной входной строкой, это означало бы, что никакой другой поток не может влиять на нашу mem-функцию, а наша функция не может влиять на любые другие вызовы в других потоках. Истина в точности противоположна, так как вы совместно используете один и тот же объект через этот указатель, который неявно дается при вызове объектов-членов. Для иллюстрации эквивалентно этому звонку

std::string a;
a.insert( ... );

без использования синтаксиса ООП будет:

std::string a;
insert( &a, ... );

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

Надеюсь, это поможет.

0 голосов
/ 10 декабря 2010

Sun WorkShop 5.0

Этот немного староват, но довольно информативен. Суть в том, что STL обеспечивает блокировки только на распределителях.

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

...