由于静态库导致的单例多实例问题
Problem facing with multiple instance of signleton due to static library
我在以下场景中面临一个静态变量问题:
我有一个单例类"Common",并创建了它的静态库libcommon.a
//common.h
class Common
{
public:
Common();
~Common();
void Show();
};
//common.cpp
Common::Common()
{cout<<"inside Common::Common"<<endl;}
Common::~Common()
{cout<<"inside Common::~Common"<<endl;}
void Common::Show()
{
static Common self;
cout<<"Address of self - "<<&self<<endl;
}
编译:g++ -ggdb -Wall -fPIC -c common.cpp
ar -cvq libcommon.a common.o
上面的库静态链接到两个动态库"libfirst.so.1.0" &"libsecond.so.1.0":
//first_so.cpp
#include "common.h"
void run_first_function()
{
Common c;
c.Show();
}
g++ -ggdb -Wall -fPIC -c firstrongo.cpp
g++ -ggdb -shared -o libfirst.so.1.0o - l。-lcommon
//second_so.cpp
#include "common.h"
void run_second_function()
{
Common c;
c.Show();
}
g++ -ggdb -Wall -fPIC -c second_so.cpp
g++ -ggdb -shared -o libsecond.so.1.0 second_so. 1.0o - l。-lcommon
最后一个测试。cpp:
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
void *lib_handle, *lib_handle1;
void (*fn)(void);
void (*fn1)(void);
int x;
char *error;
lib_handle = dlopen("/perforce/sdudhani/test/linux/libfirst.so.1.0", RTLD_LAZY);
if ((error = dlerror()) != NULL)
{
cerr<<"ERROR dlopen.."<<error<<endl;
exit(1);
}
if (!lib_handle)
{
cerr<<"ERROR while loading libfirst.so"<<endl;
exit(1);
}
lib_handle1 = dlopen("/perforce/sdudhani/test/linux/libsecond.so.1.0", RTLD_LAZY);
if (!lib_handle1)
{
cerr<<"ERROR while loading libsecond.so.1.0"<<endl;
exit(1);
}
*(void **)(&fn) = dlsym(lib_handle, "_Z18run_first_functionv");
if ((error = dlerror()) != NULL)
{
cerr<<"ERROR run_first_function.."<<error<<endl;
exit(1);
}
*(void **)(&fn1) = dlsym(lib_handle1, "_Z19run_second_functionv");
if ((error = dlerror()) != NULL)
{
cerr<<"ERROR run_second_function.."<<endl;
exit(1);
}
(*fn)();
(*fn1)();
dlclose(lib_handle);
dlclose(lib_handle1);
return 0;
}
输出:Address of self - 0x2ad08d8463c0
Address of self - 0x2ad08da483c0
机细节:
bash-3.2$ uname -a
Linux www.something.com 2.6.18-128.el5 #1 SMP Wed Dec 17 11:41:38 EST 2008 x86_64 x86_64 x86_64 GNU/Linux
bash-3.2$
我的问题是,由于上述设计,"self"被创建了两次。只是想知道是否有任何链接器/加载器选项,我应该得到自我的单个实例?
谁能告诉我如何处理这类问题?谢谢-Shrinivas
静态量在c++模块中是唯一的。c++模块是链接的单元,在你的例子中,每个动态库都是一个模块。
您需要定义您希望单例存储在哪个动态库中。然后,该库应该具有其他库引用的静态函数或变量。
如果您需要每个库独立运行,但有时需要共享一个静态库(当一起使用时),那么请考虑为每个库添加setup函数。这个函数应该在应用程序生命周期的早期被调用。该函数将每个库中的本地静态访问器指向其中一个库中的共享静态。
您还没有将Common类实现为单例。不如这样做
//common.h
class Common
{
public:
~Common();
void Show();
static Common* Instance();
private:
Common(); --must be private or else multiple instances can be created!
static Common* m_pInstance
};
//common.cpp
Common* Common::m_pInstance = NULL
Common* Common::Instance()
{
if (!m_pInstance) // Only allow one instance of class to be generated.
m_pInstance = new Common;
return m_pInstance;
}
.....
然后,你不再像以前那样创建共享资源,而是得到这样的实例:
//first_so.cpp
#include "common.h"
void run_first_function()
{
Common::instance().Show();
}
…
相关文章:
- C++中的单例实现在调用 getInstance 函数时不会产生相同的类实例
- 如何析构单例实例,或者为什么以下代码适用于析构函数?
- C++在单例类中创建类实例时遇到困难
- 多线和模板的单例比赛条件
- 使用新线程在类似于 Scott Meyer 的单例习惯用法的实现中实例化单例是否安全?
- 为什么我的单例实现两次启动?(一个进程,多个线程)
- XCode5.1 C 静态单例,但创建了多个实例
- c++单例类实例访问整个应用程序
- 如何检查是否存在单例实例,如果没有,则不创建新实例?
- 如何在不使用的情况下在 <mutex>C++11 中实现多线程安全单例
- 指针成员的 C++/CLI 包装器 - C++ 单例实例
- 为多线程环境实现单例的内存泄漏
- 单例实例化了两次
- 当周围有线程时,创建类的许多实例会失败吗?- 单例模式
- 我们是否需要互斥锁来访问 C++11 - 多线程中单例对象中的数据字段
- 为什么C++单例实例化需要do_nothing方法
- 在什么情况下,单例设计模式可能会生成同一单例类的多个实例
- Linux上跨共享库的多个单例实例
- 使用随机数生成器:多实例或单实例方法
- 由于静态库导致的单例多实例问题