关于singalton
懒汉模式
由于在生成实例的时候仅仅只是用 if(NULL == _pInstance) 进行判断
当多线程时 会产生多个线程同时 进入if(NULL == _pInstance) 从而产生多个实例 即非线程安全
`class Singleton
{
private:
class AutoRelease
{
public:
AutoRelease()
{ cout << “AutoRelease()” << endl; }
~AutoRelease()
{
cout << "~AutoRelease()" << endl;
if(_pInstance)
{
delete _pInstance;
}
}
};
public:
static Singleton * getInstance()
{
if(NULL == _pInstance)
{
_pInstance = new Singleton;
}
return _pInstance;
}
private:
Singleton(){ cout << “Singleton()” << endl; }
~Singleton(){ cout << "~Singleton()" << endl; }
private:
static Singleton * _pInstance;
static AutoRelease _auto;
};
Singleton * Singleton::_pInstance = NULL;
Singleton::AutoRelease Singleton::_auto;
int main(void)
{
Singleton * p1 = Singleton::getInstance();
Singleton * p2 = Singleton::getInstance();
printf("p1 = %p\n", p1);
printf("p2 = %p\n", p2);
return 0;
}`他叫为登记函数(函数原型:int atexit (void (*)(void))):
pthread_once()
之前提到singalton 的写法 即懒汉模式 这种写法有一个问题 当多线程调用的时候 会出现多个线程同时判断NULL ==_pinstance 而生成两个singalton 这种写法是非线程安全的
饱汉模式中
这种写法有一种好处 即在程序启动前 就会有一个实例
class singalton{
public:
static get_instance(){};
private:
static _pinstance;
}
_pintance = get_instance();
int main(){
}
模式虽然会带来线程安全 但是 由于其在程序启动前给就给类分配了一个实例 这样会造成效率下降
我们希望只有在第一个线程启用时才创建第一个实例 这就引出饿汉模式
在这里我们会使用到 pthread_once()函数
函数原形:
pthread_once_t once_control=PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control,void(*init_routine)(void));
参数:
once_control 控制变量
init_routine 初始化函数
返回值:
若成功返回0,若失败返回错误编号。
类型为pthread_once_t的变量是一个控制变量。控制变量必须使用PTHREAD_ONCE_INIT宏静态地初始化。
pthread_once函数首先检查控制变量,判断是否已经完成初始化,如果完成就简单地返回;否则,pthread_once调用初始化函数,并且记录下初始化被完成。如果在一个线程初始时,另外的线程调用pthread_once,则调用线程等待,直到那个现成完成初始话返回。
在多线程情况下 pthread_once()只会执行一次 也有只会有一个实例
`
include
include
include
using std::cout;
using std::endl;
class Singleton
{
public:
static Singleton * getInstance()
{
//pthread_once注册的init函数在多线程环境下
//永远只会被执行一次,一般用来做初始化工作
pthread_once(&_once, init);
return _pInstance;
}
static void init()
{
_pInstance = new Singleton;
atexit(destroy);
}
static void destroy()
{
if(_pInstance)
delete _pInstance;
}
private:
Singleton(){ cout << “Singleton()” << endl; }
~Singleton(){ cout << “~Singleton()” << endl;}
private:
static pthread_once_t _once;
static Singleton * _pInstance;
};
Singleton * Singleton::_pInstance = NULL;
pthread_once_t Singleton::_once = PTHREAD_ONCE_INIT;
int main(void)
{
Singleton * p1 = Singleton::getInstance();
Singleton * p2 = Singleton::getInstance();
cout << "p1 = " << p1 << endl;
cout << "p2 = " << p2 << endl;
return 0;
} `