静态变量的内存分配和初始化 对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收内存空间,因此程序结束后全局内存空间被一起回收,不存在变量依赖问题,没有任何代码会再被执行! C++引入了对象,这给全局变量的管理带领新的麻烦。C++的对象必须有构造函数生成,并最终执行析构操作。由于构造和析构并非分配内存那么简单,可以说相当复杂,因此何时执行全局或静态对象(C++)的构造和析构呢?这需要执行相关代码,无法在编译期完成,因此C++标准规定:全局或静态对象当且仅当对象首次用到时才进行构造,并通过atexit()来管理对象的生命期,在程序结束之后(如调用exit,main),按FILO顺序调用相应的析构操作! 总结:
静态变量初始化的线程安全性说明
C++11标准针规定了局部静态变量初始化需要保证线程安全,具体说明如下: 新的编译器大多对C++11的标准支持,因此也保证了这一点,但是C++03标准之前并无此说明,所以很多旧版本的编译器并不能完全支持。 注:VS2008 测试多线程的条件下虽然只有一个线程执行一次初始化,但非初始化的线程并不会等待初始化结束,而是立即返回未正确初始化的静态对象。 针对局部静态变量初始化的线程安全性,g++编译器的实现相当于使用了一个全局锁来控制一个局部静态变量的标识(标识用来判定是否已经初始化)。详情参考:http://www.cnblogs.com/xuxm2007/p/4652944.html 使用相关: 以前的标准都没有规定局部静态变量的初始化在并发模式下是否安全,很多旧版本的编译器并没有处理它的并发安全问题。因此在不支持C++11标准的编译环境下,多线程程序最好不要使用需要明显初始化的局部静态变量(对象),如果需要使用(比如单例模式中),则可以考虑使用一个全局锁或静态成员变量锁,最好不要使用局部静态变量锁,因为其本身存在一个构造的问题,多个线程获取实例的时候,可能会出现一个线程在进行锁对象构造,另一个线程则避开了构造,在锁对象还没有完全构造完成的情况下,就lock了,这个时候的行为能不能成功锁定取决于锁的实现了,虽然一般的实现不会出现问题但终归不是很严谨。
|
|