我的問題,如上所述,顯而易見,我將詳細描述該方案。 有一個名爲單用Singleton模式實現爲下面的類,在文件singleton.h:在Linux上的共享庫上存在多個單例實例
/*
* singleton.h
*
* Created on: 2011-12-24
* Author: bourneli
*/
#ifndef SINGLETON_H_
#define SINGLETON_H_
class singleton
{
private:
singleton() {num = -1;}
static singleton* pInstance;
public:
static singleton& instance()
{
if (NULL == pInstance)
{
pInstance = new singleton();
}
return *pInstance;
}
public:
int num;
};
singleton* singleton::pInstance = NULL;
#endif /* SINGLETON_H_ */
然後,有一個叫HELLO.CPP插件如下:
#include <iostream>
#include "singleton.h"
extern "C" void hello() {
std::cout << "singleton.num in hello.so : " << singleton::instance().num << std::endl;
++singleton::instance().num;
std::cout << "singleton.num in hello.so after ++ : " << singleton::instance().num << std::endl;
}
你可以看到該插件調用單例並更改單例中的屬性num。
最後,還有一個主要功能使用Singleton和插件如下:
#include <iostream>
#include <dlfcn.h>
#include "singleton.h"
int main() {
using std::cout;
using std::cerr;
using std::endl;
singleton::instance().num = 100; // call singleton
cout << "singleton.num in main : " << singleton::instance().num << endl;// call singleton
// open the library
void* handle = dlopen("./hello.so", RTLD_LAZY);
if (!handle) {
cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
// load the symbol
typedef void (*hello_t)();
// reset errors
dlerror();
hello_t hello = (hello_t) dlsym(handle, "hello");
const char *dlsym_error = dlerror();
if (dlsym_error) {
cerr << "Cannot load symbol 'hello': " << dlerror() << '\n';
dlclose(handle);
return 1;
}
hello(); // call plugin function hello
cout << "singleton.num in main : " << singleton::instance().num << endl;// call singleton
dlclose(handle);
}
和生成文件的以下內容:
example1: main.cpp hello.so
$(CXX) $(CXXFLAGS) -o example1 main.cpp -ldl
hello.so: hello.cpp
$(CXX) $(CXXFLAGS) -shared -o hello.so hello.cpp
clean:
rm -f example1 hello.so
.PHONY: clean
那麼,什麼是輸出? 我認爲有以下幾點:
singleton.num in main : 100
singleton.num in hello.so : 100
singleton.num in hello.so after ++ : 101
singleton.num in main : 101
然而,實際的輸出如下:
singleton.num in main : 100
singleton.num in hello.so : -1
singleton.num in hello.so after ++ : 0
singleton.num in main : 100
事實證明,有單件類的兩個實例。
爲什麼?
你想讓這個singleton成爲你正在執行的一個進程的單例嗎?還是一個違反所有受保護內存的「全系統」單身人士爲我們提供的? – sarnold 2011-12-24 09:06:44
除非明確說明,否則問題通常不是很明顯。你想共享庫共享單例嗎?你理論中的任何一種行爲還是實際體驗它?沒有辦法知道,除非你告訴我們。 – 9000 2011-12-24 09:07:19
@sarnold:有一個衆所周知的全系統單例模式,不受地址空間限制:它被稱爲服務器。但直到原始海報告訴他的代碼的_purpose_,很難說這個模式是否合適。 – 9000 2011-12-24 09:12:11