c++ 函数指针赋值是安全的吗?

c++ function pointer assignment is safe?

这段代码线程安全吗?

static PFN_SOMEFUNC pfnSomeFunc = nullptr;

PFN_SOMEFUNC SomeFuncGetter();

void CalledFromManyThreads() {
    if (pfnSomeFunc == nullptr)
        pfnSomeFunc = SomeFuncGetter();

    pfnSomeFunc();
}

这不是原子指针操作题。有一些特殊情况。

它看起来不是线程安全的,因为全局变量可以被任何线程修改而无需同步。即使是一个赋值也不能保证是原子的。

可以做的是利用一种语言特性,通过将静态变量移动到你的函数中来保证线程安全的原子初始化(静态初始化惨败的一种非常常见的解决方案):

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();
}