【发布时间】:2018-11-20 16:59:51
【问题描述】:
我已经实现了这样的标准单例模式(非线程版本):
hpp:
#ifndef SERVICEMANAGER_H
#define SERVICEMANAGER_H
#include <QObject>
#include <QVariant>
#include <QMap>
#include "IService.h"
#include "qhcore_global.h"
#include <QDebug>
class ServiceManager : public QObject
{
Q_OBJECT
public:
static ServiceManager* instance();
~ServiceManager(){qDebug()<<Q_FUNC_INFO;}
IService* service(QString name);
bool registerService(IService* service);
private:
explicit ServiceManager(QObject *parent = nullptr);
QMap<QString, IService*> _serviceMap;
static ServiceManager* __instance;
signals:
void serviceAdded(QString serviceName);
public slots:
};
#endif // SERVICEMANAGER_H
cpp:
ServiceManager* ServiceManager::__instance = nullptr;
ServiceManager::ServiceManager(QObject *parent) : QObject(parent)
{
qDebug()<<"CREATE::CTOR";
}
ServiceManager* ServiceManager::instance()
{
qDebug()<< __instance << "BEFORE";
if(__instance == nullptr)
{
qDebug()<<"CREATE";
__instance = new ServiceManager();
qDebug()<< __instance << "AFTER";
}
return __instance;
}
我的日志是这样的
[DEBUG 17.11. - 17:50:18:748] --
[DEBUG 17.11. - 17:50:18:748] -- QObject(0x0) BEFORE
[DEBUG 17.11. - 17:50:18:748] -- CREATE
[DEBUG 17.11. - 17:50:18:748] -- CREATE::CTOR
[DEBUG 17.11. - 17:50:18:748] -- ServiceManager(0x55e9fc6fb510) AFTER
[DEBUG 17.11. - 17:50:18:748] -- 0
[INFO 17.11. - 17:50:18:748] -- "Service registered: lab"
[DEBUG 17.11. - 17:50:18:748] -- 1
[INFO 17.11. - 17:50:18:749] -- "Added Resource factory for synclist for descriptor: labcontrol/logs"
[INFO 17.11. - 17:50:18:749] -- "Added Resource factory for synclist for descriptor: labcontrol/users"
[INFO 17.11. - 17:50:18:749] -- "Added Resource factory for synclist for descriptor: labcontrol/permissions"
[INFO 17.11. - 17:50:18:749] -- "Added Resource factory for synclist for descriptor: labcontrol/cards"
[INFO 17.11. - 17:50:43:973] -- "::ffff:192.168.1.32" has connected.
[INFO 17.11. - 17:50:43:985] -- "admin logged in. (" 1 sessions open)
[INFO 17.11. - 17:50:43:985] -- Device registered: "4f2o4o7b1a1r"
[INFO 17.11. - 17:50:44:003] -- Create ListResource with FS Resource Handler "logger/mappings_synclist"
[INFO 17.11. - 17:50:44:005] -- Create ListResource with FS Resource Handler "labcontrol/logs_synclist"
[INFO 17.11. - 17:50:44:007] -- Create ListResource with FS Resource Handler "labcontrol/users_synclist"
[INFO 17.11. - 17:50:44:009] -- Create ListResource with FS Resource Handler "labcontrol/permissions_synclist"
[INFO 17.11. - 17:50:44:011] -- Create ListResource with FS Resource Handler "labcontrol/cards_synclist"
[DEBUG 17.11. - 17:50:45:136] -- QObject(0x0) BEFORE
[DEBUG 17.11. - 17:50:45:136] -- CREATE
[DEBUG 17.11. - 17:50:45:136] -- CREATE::CTOR
[DEBUG 17.11. - 17:50:45:137] -- ServiceManager(0x55e9fc749340) AFTER
[DEBUG 17.11. - 17:50:45:137] -- COUNT: 0
[DEBUG 17.11. - 17:50:45:137] -- ()
[WARNING 17.11. - 17:50:45:138] -- "Unavailable servcie: lab"
在日志中可以看到单例会被实例化两次。我第二次调用 instance() 函数时,私有静态成员 __instance 再次持有一个 nullptr。这很奇怪。相同的代码可以在不同平台(OSx、Raspbian、...)的其他机器上完美运行。
我的系统是运行 Ubuntu Server 18.10, x64 的 beelink BT3 pro。代码本身是一个基于 WebSocket 的物联网云,它结合了 Qt5 和插件。
我尝试了什么:
使用不同的编译器,例如 gcc-8、gcc-7 和 gcc-6。 我自己编译 Qt 以确保所有二进制文件都使用相同的编译器构建。
再次:我的应用程序使用插件。这可能与单例对象在不同插件中使用这一事实有关,在运行时通过 QPluginLoader 从共享对象文件加载。
编辑:我不使用线程,也不使用不同的命名空间。
欢迎任何提示!提前致谢!
EDIT2 (解决方案):
(移至下面我的答案。)
【问题讨论】:
-
这个cpp文件是应用程序的一部分还是插件的一部分?
-
多线程?初始化时的竞争条件?
-
与您的问题无关,但请注意,以双下划线开头的符号在任何地方都为编译器和标准库保留。参见例如this old answer 了解更多详情。
-
-没有线程(见编辑)。此代码是插件的一部分。整个应用程序由插件组成。应用程序本身只是一个插件加载器。
-
@FriedemannMetzger 在所以你没有添加 SOLVED 或类似问题的标题,指出问题已解决的方法是将响应标记为正确,如果没有答案帮助您然后我们邀请您发布答案,您可以在 2 天内将其标记为正确。 :-)