考虑以下场景。我们有一个带有静态局部变量的 C++ 函数:
void function()
{
static int variable = obtain();
//blahblablah
}
该函数需要同时从多个线程调用,因此我们添加一个临界区以避免并发访问静态本地:
void functionThreadSafe()
{
CriticalSectionLockClass lock( criticalSection );
static int variable = obtain();
//blahblablah
}
但这就足够了吗?我的意思是有一些魔法可以使变量初始化不超过一次。因此,运行时维护了一些服务数据,指示每个静态本地是否已初始化。
上述代码中的关键部分也会保护该服务数据吗?这种情况需要额外的保护吗?
C++ 规定静态变量只能初始化一次——但是 C++ 还不处理线程。
gcc(至少在 *nix 系统上)发挥了适当的作用来安全地保护初始化此类静态变量的多个线程。根据这个链接,msvc 则不会 - 在这种情况下,您必须自己锁定初始化。
用关键部分保护初始化应该保护所有这些 - 即你的 functionThreadSafe() 是可以的 - (除非obtain()
本身调用functionThreadSafe()
这篇博客文章在这方面值得一读。
就我个人而言,为了避免意外,我会尝试重写它,以便您可以初始化variable
在创建任何线程之前,您自己一次 - 例如
static int variable = 0;
void init_variable() //call this once, at the start of main()
{
variable = obtain();
}
void function()
{
//use variable, lock if you write to it
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)