У меня есть коллекция, которую я защищаю с помощью мьютекса. После инициализации он только читается, поэтому мне не нужен мьютекс.Глобальная статическая инициализация threading
Коллекция инициализируется и заполняется глобальными статическими инициализаторами. Я знаю, что глобальная статическая инициализация гарантируется в пределах одной единицы перевода. Есть ли гарантия, что глобальная статическая инициализация будет однопоточной?
У меня есть статическая коллекция, защищенная счетчиком Шварца и заполняемая конструкторами других статических объектов. Контейнер связан с мьютексом. Учитывая, что коллекция доступна только для чтения после запуска main
, я хотел бы избавиться от мьютекса, если я могу гарантировать, что статические конструкторы вызываются в одном потоке.
Мое понимание состоит в том, что статический порядок инициализации обычно хорошо определен в пределах одной единицы перевода, но не определен между единицами перевода. Позволяет ли стандарту инициализировать/создавать статические объекты с помощью разных потоков времени выполнения?
Schwarz счетчик:
Заголовок файла:
struct Init
{
Init();
~Init();
};
namespace
{
Init _init;
}
extern std::map<int, std::unique_ptr<...>> &protected;
Исходный файл:
namespace
{
int init_count;
std::aligned_storage<sizeof(std::map<int, std::unique_ptr<...>>), alignof(std::map<int, std::unique_ptr<...>>>)> protected_storage;
}
std::map<int, std::uniqe_ptr<...>> &protected = *reinterpret_cast<std::map<int, std::unique_ptr<...>> *>(&protected_storage);
Init::Init()
{
if (!init_counter++)
{
new(&protected_storage) std::map<int, std::unique_ptr<...>>();
}
}
Init::~Init()
{
if (!--init_counter)
{
protected.~std::map<int, std::unique_ptr<...>>();
}
}
Коллекция населения:
struct helper
{
helper(...)
{
protected.insert(std::make_pair(...));
}
};
Макрос разворачивается, что создает статические экземпляры помощника.
В C++ 11 статическая инициализация не вводит гонку данных. –
Статическая инициализация - либо инициализация нуля, либо * постоянная инициализация *. Я не думаю, что у вас могут быть наблюдаемые различия между многопоточными и однопоточными * static * init (нелокальных переменных). – dyp
Действительно ли мы говорим о глобальных статических инициализаторах, или мы также рассматриваем конструкторы статических объектов? – jxh