Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中的线程安全单例+;GCC4之后?_C++_Multithreading_Gcc_Static_Thread Safety - Fatal编程技术网

C++ C+中的线程安全单例+;GCC4之后?

C++ C+中的线程安全单例+;GCC4之后?,c++,multithreading,gcc,static,thread-safety,C++,Multithreading,Gcc,Static,Thread Safety,我听说在gcc的某个版本中使用了如下内容: static A* a = new A(); return a; 对于一个单身汉来说是线程安全的,而且你不再需要从say改编的东西了 是否有人提供了我可以阅读的具体参考或链接?标准草案(n3337.pdf)第6.7节,第4点: 具有静态存储持续时间(3.7.1)或线程存储的所有块作用域变量的零初始化(8.5) 持续时间(3.7.2)在任何其他初始化发生之前执行。系统的恒定初始化(3.6.2) 具有静态存储持续时间的块作用域实体(如果适用)在首次输入其

我听说在gcc的某个版本中使用了如下内容:

static A* a = new A();
return a;
对于一个单身汉来说是线程安全的,而且你不再需要从say改编的东西了


是否有人提供了我可以阅读的具体参考或链接?

标准草案(n3337.pdf)第6.7节,第4点:

具有静态存储持续时间(3.7.1)或线程存储的所有块作用域变量的零初始化(8.5) 持续时间(3.7.2)在任何其他初始化发生之前执行。系统的恒定初始化(3.6.2) 具有静态存储持续时间的块作用域实体(如果适用)在首次输入其块之前执行。 允许一个实现使用静态或静态变量对其他块作用域变量执行早期初始化 允许实现静态初始化的相同条件下的线程存储持续时间 命名空间范围内具有静态或线程存储持续时间的变量(3.6.2)。否则,这样的变量是 控件第一次通过其声明时初始化;这样的变量被认为是在 完成其初始化。如果初始化通过抛出异常退出,则初始化 未完成,因此将在控件下次输入声明时重试如果控件进入 在初始化变量时并发声明,并发执行应等待 初始化完成.88如果控件在变量运行时递归地重新输入声明
初始化后,行为未定义。

标准草案(n3337.pdf)第6.7节第4点:

具有静态存储持续时间(3.7.1)或线程存储的所有块作用域变量的零初始化(8.5) 持续时间(3.7.2)在任何其他初始化发生之前执行。系统的恒定初始化(3.6.2) 具有静态存储持续时间的块作用域实体(如果适用)在首次输入其块之前执行。 允许一个实现使用静态或静态变量对其他块作用域变量执行早期初始化 允许实现静态初始化的相同条件下的线程存储持续时间 命名空间范围内具有静态或线程存储持续时间的变量(3.6.2)。否则,这样的变量是 控件第一次通过其声明时初始化;这样的变量被认为是在 完成其初始化。如果初始化通过抛出异常退出,则初始化 未完成,因此将在控件下次输入声明时重试如果控件进入 在初始化变量时并发声明,并发执行应等待 初始化完成.88如果控件在变量运行时递归地重新输入声明
初始化后,行为未定义。

GCC遵循交叉供应商。涉及函数局部静态的线程安全初始化的相关章节包括和,其中说明:

预期不支持多线程的实现可能只是检查该保护变量的第一个字节(即地址最低的字节),当且仅当其值为零时初始化,然后将其设置为非零值

但是,打算自动支持线程安全一次性初始化的实现(与要求显式用户控制线程安全相反)可以使用以下API函数:

在该API的早期GCC实现中有一些bug,我认为它们都已修复,并且在GCC版本4.3中可以正常工作(可能更早,我记不起来了,现在也找不到参考。)


然而,坏模式,不要使用它

GCC遵循交叉供应商。涉及函数局部静态的线程安全初始化的相关章节包括和,其中说明:

预期不支持多线程的实现可能只是检查该保护变量的第一个字节(即地址最低的字节),当且仅当其值为零时初始化,然后将其设置为非零值

但是,打算自动支持线程安全一次性初始化的实现(与要求显式用户控制线程安全相反)可以使用以下API函数:

在该API的早期GCC实现中有一些bug,我认为它们都已修复,并且在GCC版本4.3中可以正常工作(可能更早,我记不起来了,现在也找不到参考。)


然而,坏模式,不要使用它

实际上,您不需要使用事件操作符new来创建单例。因此,不需要关键部分。@MFontanii:使用
new
避免了破坏顺序的失败,而代价是内存泄漏。在C++中没有一个很好的方法来实现一个单独的,但是有很多坏方法。@ MikeSeymour:我仍然会返回一个引用……是的,线程安全的单模式是:不要使用单体。事实上,不需要使用new new来创建单体。因此,不需要关键部分。@MFontanii:使用
new
避免了破坏顺序的失败,而代价是内存泄漏。在C++中没有一个实现单体的好方法,但是有很多坏方法。@ MikeSeymour:我仍然会返回一个引用……是的,线程安全的单模式是:不要使用单体。gcc在这种情况下通过抛出一个特定的异常来保护它。这不是创建单例。关于递归位,gcc在这种情况下通过抛出一个特定的异常来保护它。这不是创建单例。