在C 中,可以从第三个共享对象访问其他两个不同共享对象
In C++, can two other different shared objects access a Singleton from a third shared object?
i在C 中有一个应用程序,该应用程序通过共享对象从两个或多个插件(每个插件)加载大部分代码(每个插件)。我使用以下代码加载插件:
pluginHandle = dlopen(fileName, RTLD_NOW|RTLD_GLOBAL);
init_t* init = (init_t*) dlsym(pluginHandle, "init") // Create should return an instance of the class of the plugin
plugin = init();
我到达了我需要两个插件来开始将数据添加到常见Queue
的地步。由于该应用程序不允许在两个插件之间进行通信,而无需更改应用程序本身中的代码(我们要避免的一点),所以我想我找到了一种解决方法:第三个插件,其中包括带有一个带有一个带有a的singleton类线程安全Queue
。
然后,我将重新编译并将两个插件链接到库,然后使用getInstance()
来获取单例并开始将任务添加到队列中。
这是安全的实施吗?Singleton Queue
可以工作吗?
动态库(共享对象),其中包括一个带有线程安全队列的单例类。
当您只想限制一个类仅实例化一次时,使用单身人士。那是不是您想要的:您希望所有插件都可以在类的特定实例上工作。这里没有"只有一个人可以活"的要求。
使用Meyer的模式在C 11中的线程安全单例可能是这样的:
class Singleton
{
private:
Singleton();
public:
Singleton(const &Singleton) = delete;
Singleton& operator=(const &Singleton) = delete;
static Singleton& get_instance()
{
static Singleton s;
return s;
}
};
默认构造函数是私人声明的,并且删除了复制/分配操作以避免多个实例。
您需要更简单的内容:一个函数总是返回同一实例。这样的东西:
class Manager
{
public:
static Resource& get_resource()
{
static Resource r;
return r;
}
};
无需防止多重实例化:如果您想要相同的实例,请要求同一实例。
您还可以使用资源池扩展设计,返回一个ID的同一实例:
enum class ResourceId
{
ID_FOR_A_FAMILY_OF_PLUGIN,
ID_FOR_AN_OTHER_FAMILY_OF_PLUGIN
};
class Pool
{
public:
static Resource& get_resource(ResourceId id)
{
static std::map<ResourceId, Resource> p;
return p[id];
}
};
请注意,在此示例中,p[id]
是用Resource
的默认构造函数即时创建的。您可能需要在施工期间通过参数:
class Resource
{
public:
Resource():ready(false){}
void init(some parameters)
{
// do some intialization
ready = true;
}
bool is_ready() const { return ready; }
private:
bool ready;
};
class Pool
{
public:
static Resource& get_resource(ResourceId id)
{
static std::map<ResourceId, Resource> p;
auto& r = p[id];
if(!r.is_ready())
{
r.init(some parameters);
}
return r;
}
};
或使用指针允许多态性:
class Pool
{
public:
static std::unique_ptr<Resource>& get_resource(ResourceId id)
{
static std::map<ResourceId, std::unique_ptr<Resource>> p;
auto& r = p[id];
if(!r)
{
r = std::make_unique<SomeResourceTypeForId>(some parameters);
}
return r;
}
};
请注意,最后两个实现需要围绕非静态代码的静音才能进行线程安全。
相关文章:
- 处理影响跨不同线程共享对象的定时回调的最佳方法是什么?
- 如何创建一个共享对象与另一个.所以在Cmake
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 在 Android Studio 中使用 C++ 共享对象时出现问题
- 共享对象、符号、C/C++ 库链接和加载
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 在 win32 上生成 R 包:无法加载共享对象 (.dll)
- 共享对象中的符号
- sf::Windows上的音乐:api-ms-win-crt-locale-l1-1-0.dll:无法打开共享对象文件
- C++ 为什么要级联共享对象链接
- 加载共享库时出错:libbsoncxx.so._noabi:无法打开共享对象文件:没有此类文件或目录
- 从单个.cpp构建共享对象
- 与 32 位共享对象的链接问题
- 卸载共享对象(.so 文件)在 C++ 中用 dlopen() 打开
- 运行程序时找不到共享对象库,但在编译过程中链接了它
- 错误:无法打开共享对象文件:没有此类文件或目录
- Qt 创建器:将库移动到 subdir 后无法打开共享对象文件
- 共享对象中的符号名称与文件中.cpp函数不同
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- Cython:共享对象中未定义的符号