Подтвердить что ты не робот

Является ли С++ STL потокобезопасным для разных контейнеров (с использованием реализации STLport)?

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

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

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

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

4b9b3361

Ответ 1

SGI STL

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

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

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

g++

libstdС++ docs

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

STLPort

Документы STLPort

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

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

Ответ 2

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

Нынешний стандарт С++ не адресует проблемы concurrency вообще, так что по крайней мере пока нет требования, которое применяется ко всем реализациям.

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

Ответ 3

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

Ответ 4

Sun WorkShop 5.0

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

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

Ответ 5

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

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

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

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

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

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