我有一個集合,我用互斥鎖保護。初始化後它只能被讀取,所以我不需要在那裏有一個互斥體。全局靜態初始化線程
集合已初始化並填充到全局靜態初始化程序中。我知道全局靜態初始化是在一個單獨的翻譯單元中保證的。有沒有保證全局靜態初始化是單線程的?
我有一個靜態集合,受Schwarz計數器保護,並由其他靜態對象的構造函數填充。該容器與一個互斥體相關聯。鑑於集合在main
開始之後是隻讀的,如果我可以保證在單個線程中調用靜態構造函數,我希望擺脫互斥鎖。
我的理解是,靜態初始化順序通常在單個翻譯單元內定義良好,但在翻譯單元之間未指定。該標準是否允許靜態對象由不同的運行時提供的線程初始化/構建?
施瓦茨計數器:
頭文件
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