'const static' STL 容器初始化(可重入函数内部)

Ami*_*mit 1 c++ static multithreading constructor stl

假设这是一个为多个线程提供服务的函数。他们读kHKeys不受保护,因为从同一内存地址读取-读取不是数据争用。

\n

但是,在读一读时,kHKeys就被构建了。有可能在构造过程中,另一个线程进入了reentrantFunction函数。

\n

是否有必要构建kHKeys在释放同时调用 reentrantFunction 的线程之前

\n

例子:

\n
int reentrantFunction(const std::wstring& key_parent_c)\n{\n    // const 'static' means that kHKeys is constructed only once \xe2\x80\x94\n    // The 1st the function is run \xe2\x80\x94 and put into a shared memory space.\n    // Otherwise, kHKeys is local and it must be constructed each time the function is called.\n    const static std::map<std::wstring, HKEY> kHKeys{ { L"HKEY_CURRENT_USER", HKEY_CURRENT_USER } ,\n        { L"HKEY_LOCAL_MACHINE", HKEY_LOCAL_MACHINE } , { L"HKEY_CLASSES_ROOT", HKEY_CLASSES_ROOT } ,\n        { L"HKEY_CURRENT_CONFIG", HKEY_CURRENT_CONFIG } , { L"HKEY_CURRENT_USER_LOCAL_SETTINGS", HKEY_CURRENT_USER_LOCAL_SETTINGS } ,\n        { L"HKEY_PERFORMANCE_DATA", HKEY_PERFORMANCE_DATA } , { L"HKEY_PERFORMANCE_NLSTEXT", HKEY_PERFORMANCE_NLSTEXT } ,\n        { L"HKEY_PERFORMANCE_TEXT", HKEY_PERFORMANCE_TEXT } , { L"HKEY_USERS", HKEY_USERS } };\n\n    // Use kHKeys \n
Run Code Online (Sandbox Code Playgroud)\n

woh*_*tad 5

kHKeys线程开始使用之前不必构造reentrantFunction

正如你在这里看到的:静态局部变量,从C++11开始,标准就保证静态局部变量只会被初始化一次。有一个关于可用于确保多线程环境中的单一初始化的锁的具体注释:

如果多个线程尝试同时初始化同一个静态局部变量,则初始化只会发生一次(使用 std::call_once 可以为任意函数获得类似的行为)。
注意:此功能的通常实现使用双重检查锁定模式的变体,这将已初始化的本地静态变量的运行时开销减少到单个非原子布尔比较。

但是- 如果您使用需要相对较长初始化的静态变量(不是您示例中的情况),并且您的线程需要根据某些实时要求(具有最小延迟)执行,则可以考虑在单独的初始化中进行阶段,线程开始运行之前。

  • 另请注意,某些 STL 容器现在是 constexpr,编译器可能会在编译时构造该值并将其放置在 .data 部分中。您可以(尝试)通过声明它为 constit 来强制执行此操作。 (2认同)