C++11 引入了线程安全的本地静态初始化,又名“魔法静态”:Is local static variable initialization thread-safe in C++11?
特别是,规范说:
If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization.
所以这里有一个隐式互斥锁。这非常有趣,而且似乎是一个异常现象——也就是说,我不知道 c++ 中内置的任何其他隐式互斥体(即不使用 std::mutex 之类的东西的互斥体语义)。还有其他的吗,或者这个在规范中是独一无二的?
我也很好奇是否可以利用 magic static 的隐式互斥锁(或其他隐式互斥锁,如果有的话)来实现其他同步原语。例如,我看到它们可用于实现 std::call_once,因为:
std::call_once(onceflag, some_function);
可以这样表示:
static int dummy = (some_function(), 0);
但是请注意,魔术静态版本比 std::call_once 更受限制,因为使用 std::call_once 您可以重新初始化一次标志,因此每次程序执行多次使用代码,而使用魔术静态,您实际上每次程序执行只能使用一次。
这是我能想到的唯一不太明显的魔术静力学用法。
是否可以使用 magic static 的隐式互斥锁来实现其他同步原语,例如通用的 std::mutex 或其他有用的东西?
最佳答案
block 作用域static
变量的初始化是语言 唯一需要同步的地方。一些库函数需要同步,但不是直接同步函数(例如 atexit
)。
由于本地 static
的初始化同步是一次性的事情,即使不是不可能,也很难在其之上实现通用同步机制,因为每个当您需要一个同步点时,您需要初始化一个不同的本地static
对象。
虽然在某些情况下它们可以用来代替 call_once
,但它们不能用作一般替代品,因为给定的 once_flag
对象可能是从许多地方使用。
关于multithreading - magic statics : similar constructs, 有趣的非显而易见的用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42917709/