【发布时间】:2021-12-14 04:16:27
【问题描述】:
这段代码线程安全吗?
static PFN_SOMEFUNC pfnSomeFunc = nullptr;
PFN_SOMEFUNC SomeFuncGetter();
void CalledFromManyThreads() {
if (pfnSomeFunc == nullptr)
pfnSomeFunc = SomeFuncGetter();
pfnSomeFunc();
}
这不是原子指针操作的问题。有一些特殊情况。
- SomeFuncGetter() 总是返回相同的地址。
- SomeFuncGetter() 是线程安全的。
【问题讨论】:
-
不是。用
std::atomic包裹pfunSomeFunc。 -
您可以将其设为静态 local 变量,并从 C++ 标准中的 this awesome quirk 中受益。
-
代码中没有使用同步,因此您发布的代码中没有线程安全。在此代码之外会发生什么 - 这是您发布并提出问题的唯一代码。
-
它不是线程安全的。
pfnSomeFunc = SomeFuncGetter();=本身不是线程安全的。也许,就在 30 年前,代码是“线程安全的”,因为处理器不那么复杂。但是在这个时代,比较和赋值(加上仅仅使用boolean标志)不会让你获得线程安全。只有使用适当的同步才能为您提供这些结果。 -
@chaeyk 是的,有一个“同步问题”。您断言
pfSomeFunc只能有一个值是不正确的 - 代码指定了两个值(nullptr在初始化时,SomeFuncGetter()在后续分配中返回的值)。由于此代码中没有同步,因此存在竞争条件会影响pfSomeFunc与nullptr的比较和分配 - 这些操作中的任何一个(或两个)都可能被另一个操作抢占(因为两个操作都不是原子的)部分完成时线程。
标签: c++ function-pointers