C++的static线程安全的实现细节是什么?

C++的局部static变量,是预先在静态存储区分配了内存,然后在第一次执行到这里的时候进行初始化的吗?此外static的线程安全,内部有维护一个fl…
关注者
36
被浏览
39,855

9 个回答

~~~~

static变量的初始化分为静态初始化(static initialization)和动态初始化(dynamic initialization)。静态初始化就是编译期算出初始值,运行期什么都不用做(C++20可以用 constinit 要求静态初始化,做不到就报错)。动态初始化才有初始化顺序、线程安全之类的麻烦事。

上面链接里就是 Itanium C++ ABI 定义的用于动态初始化的接口(ARM虽然是基于此,但是细节略有不同)。至于具体实现用atomic还是别的什么,光libsupc++( gcc.gnu.org Git - gcc.git/blob - libstdc++-v3/libsupc++/guard.cc )就有三种做法

你说的是局部静态变量,那就是函数中的static了。这(至少)得分两种情况。

一、如果静态变量类型是基础类型,比如 int , char 等……我怀疑编译器做手脚了,它直接就分配并初始化好在那里,不管你访不访问,它就在那里——结果就是执行速度性能上毫无影响。

二、如果是结构(包括class)类型, 那就是加代码段锁了——因为这里需要调用函数(典型的如构造函数),或者任何其它语句,比如 你调用 new 分配内存;那么所在函数每次进入时都会有一个附加的加锁除锁。


各给个例子:

// 例1
int i()
     static int a = 10;  //毫不影响 i() 的执行性能,a 是个该函数内可见的全局生命周期变量
     return a;
// 例2
std::string s()
     static std::string a {"hello"}; //这行会有加锁除锁包围
     return a;
// 例3: