Multithreading C++;11使用lambda和call#u once的线程安全单例:主函数(g+;+;,clang+;+;,Ubuntu 14.04)

Multithreading C++;11使用lambda和call#u once的线程安全单例:主函数(g+;+;,clang+;+;,Ubuntu 14.04),multithreading,c++11,lambda,singleton,Multithreading,C++11,Lambda,Singleton,全部 我不熟悉C++11及其许多特性 我正在寻找一个使用lambda和call\u once的线程安全单例的C++11(非boost)实现(抱歉……我无权在帖子中包含call\u once标记) 我已经做了很多调查(我正在使用g++(4.8,5.x,6.2),clang++3.8,Ubuntu 14.04,试图避免使用boost),我发现了以下链接: (看起来与前一个非常相似,但更完整,并在最后提供了自己的实现) 但是:我在上述实现中遇到了这些问题:或者我编写了一个错误的主函数实现(可能),或

全部

我不熟悉C++11及其许多特性

我正在寻找一个使用
lambda
call\u once
线程安全单例
的C++11(非boost)实现(抱歉……我无权在帖子中包含
call\u once
标记)

我已经做了很多调查(我正在使用g++(4.8,5.x,6.2),clang++3.8,Ubuntu 14.04,试图避免使用boost),我发现了以下链接:

(看起来与前一个非常相似,但更完整,并在最后提供了自己的实现)

但是:我在上述实现中遇到了这些问题:或者我编写了一个错误的主函数实现(可能),或者发布的代码中有错误(不太可能),但是我收到了不同的编译/链接错误(当然,这两种错误是同时发生的……)

下面的代码也会发生类似的情况,它似乎是根据注释编译的(但这段代码不使用lambda,也不调用_一次):

(在本例中,它编译良好,但在运行时抛出以下错误):

在抛出“std::system\u error”实例后终止调用

what():未知错误-1

中止(堆芯转储)

那么,你能帮助我,在主函数中调用getInstance()的正确方法,得到一个(并且只有一个对象),然后,如何调用我可能包含在单例中的其他函数吗?(类似于:Singleton::getInstance()->myFx(x,y,z)

(注意:我在StackOverflow中也发现了一些引用,它们被解析为“线程安全”,但在其他StackOverflow帖子和其他不被视为“线程安全”的互联网场所中也有类似的实现;这里有两个例子(它们不使用lambda)):


最后,如果您能向我推荐关于这些主题的最佳书籍,我将不胜感激。提前感谢!!

我刚刚遇到了这个问题。在我的情况下,我需要将-lpthread添加到我的编译选项中。

我刚刚遇到了这个问题。在我的情况下,我需要将-lpthread添加到我的编译选项中。

用一个静态变量定义一个单例,如所建议的,对于C++11是线程安全的。对于C++11,静态变量的初始化定义为在 只有一个线程,在初始化完成之前不会有其他线程继续进行(我还可以用我们最近在嵌入式平台上遇到的问题来备份这个问题,当时我们使用call_once实现了一个单例,在我们使用静态变量返回到“经典”单例实现之后,它就工作了。)

ISO/IEC 14882:2011在§3.6.2中定义如下:

静态初始化应在任何动态初始化发生之前进行

作为§6.7的一部分:

所有具有静态变量的块范围变量的零初始化(8.5) 存储持续时间(3.7.1)或线程存储持续时间(3.7.2)为 在进行任何其他初始化之前执行

(另见)


我可以推荐的一本好书是A.Williams的《C++并发操作》(作为第3章的一部分,我们将调用_一次,并讨论单例模式——这就是为什么我知道自C++11以来,“经典单例”是线程安全的。)

使用静态变量实现一个单例,如所建议的,对于C++11是线程安全的。对于C++11,静态变量的初始化定义为在 只有一个线程,在初始化完成之前不会有其他线程继续进行(我还可以用我们最近在嵌入式平台上遇到的问题来备份这个问题,当时我们使用call_once实现了一个单例,在我们使用静态变量返回到“经典”单例实现之后,它就工作了。)

ISO/IEC 14882:2011在§3.6.2中定义如下:

静态初始化应在任何动态初始化发生之前进行

作为§6.7的一部分:

所有具有静态变量的块范围变量的零初始化(8.5) 存储持续时间(3.7.1)或线程存储持续时间(3.7.2)为 在进行任何其他初始化之前执行

(另见)


我可以推荐的一本好书是A.Williams的《C++并发操作》(作为第3章的一部分,我们将调用_一次,并讨论单例模式——这就是为什么我知道自C++11以来,“经典单例”是线程安全的。)

@Pablo Esteban Camacho:谢谢你的回答!事实上,这让我更清楚地认识到使用call_一次的安全性,以及该工具相对于经典解决方案(互斥)的改进@Pablo Esteban Camacho:谢谢你的回答!事实上,这让我明白了一次使用call_的安全性,以及该工具相对于经典解决方案(互斥)的改进。