c++ 函数指针赋值是安全的吗?
c++ function pointer assignment is safe?
这段代码线程安全吗?
static PFN_SOMEFUNC pfnSomeFunc = nullptr;
PFN_SOMEFUNC SomeFuncGetter();
void CalledFromManyThreads() {
if (pfnSomeFunc == nullptr)
pfnSomeFunc = SomeFuncGetter();
pfnSomeFunc();
}
这不是原子指针操作题。有一些特殊情况。
- SomeFuncGetter() 始终returns 相同的地址。
- SomeFuncGetter() 是线程安全的。
它看起来不是线程安全的,因为全局变量可以被任何线程修改而无需同步。即使是一个赋值也不能保证是原子的。
你可以做的是利用一种语言特性,通过将静态变量移动到你的函数中来保证线程安全的原子初始化(静态初始化惨败的一种非常常见的解决方案):
void CalledFromManyThreads() {
static PFN_SOMEFUNC pfnSomeFunc = SomeFuncGetter();
pfnSomeFunc();
}
现在它是线程安全的。如果你需要在多个地方缓存结果,你可以包装它:
PFN_SOMEFUNC GetSomeFunc()
{
static PFN_SOMEFUNC pfnSomeFunc = SomeFuncGetter();
return pfnSomeFunc;
}
void CalledFromManyThreads() {
PFN_SOMEFUNC pfnSomeFunc = GetSomeFunc();
pfnSomeFunc();
}
这段代码线程安全吗?
static PFN_SOMEFUNC pfnSomeFunc = nullptr;
PFN_SOMEFUNC SomeFuncGetter();
void CalledFromManyThreads() {
if (pfnSomeFunc == nullptr)
pfnSomeFunc = SomeFuncGetter();
pfnSomeFunc();
}
这不是原子指针操作题。有一些特殊情况。
- SomeFuncGetter() 始终returns 相同的地址。
- SomeFuncGetter() 是线程安全的。
它看起来不是线程安全的,因为全局变量可以被任何线程修改而无需同步。即使是一个赋值也不能保证是原子的。
你可以做的是利用一种语言特性,通过将静态变量移动到你的函数中来保证线程安全的原子初始化(静态初始化惨败的一种非常常见的解决方案):
void CalledFromManyThreads() {
static PFN_SOMEFUNC pfnSomeFunc = SomeFuncGetter();
pfnSomeFunc();
}
现在它是线程安全的。如果你需要在多个地方缓存结果,你可以包装它:
PFN_SOMEFUNC GetSomeFunc()
{
static PFN_SOMEFUNC pfnSomeFunc = SomeFuncGetter();
return pfnSomeFunc;
}
void CalledFromManyThreads() {
PFN_SOMEFUNC pfnSomeFunc = GetSomeFunc();
pfnSomeFunc();
}