首先看一個簡單的單線程的單例模式
(1)構造函數私有化
(2)提供一個全局的靜態方法(靜態訪問點)
(3)在類中定義一個靜態指針,指向本類的變量 的靜態變量指針
#include<iostream>
using namespace std;
class singelton
{
public:
static singelton* getinstance()
{
if (m_psl == NULL)
{
m_psl = new singelton;
}
return m_psl;
}
static void free_instance()
{
if (m_psl != NULL)
{
delete m_psl;
}
m_psl = NULL;
}
private:
singelton()
{
cout << "singelton contructor" << endl;
}
private:
static singelton *m_psl;
};
int main()
{
singelton* ps1 = singelton::getinstance();
singelton* ps2 = singelton::getinstance();
if (ps1 == ps2)
{
cout << "the same" << endl;
}
else
{
cout << "diffence" << endl;
}
system("pause");
return 0;
}
都知道多線程下,全局的變量訪問順序都是隨機的,對於 單例變量也是如此,不加鎖就會在每個線程中都創建一個實例,此時就不是單例了
如下是一個簡單的多線程下的單例實現(win)
#include"windows.h"
#include"winbase.h"
#include<process.h>
using namespace std;
CRITICAL_SECTION cs; //定義一個臨界區變量 ,用來對singleton的初始化函數加鎖
class singleton
{
private:
singleton() //多線程下不是線程安全函數
{
cout << "構造函數" << endl;
//Sleep(1000);
}
~singleton();
public:
static singleton* get_singleton()
{
EnterCriticalSection(&cs); // 開始加鎖,在沒有解鎖前只有一個線程可以訪問
if (single == NULL)
{
count++;
single = new singleton();
}
LeaveCriticalSection(&cs); //解鎖
//另一種double check的方法
/*-----------------------------------
if (single == NULL)
{
EnterCriticalSection(&cs);
if (single == NULL)
{
count++;
single = new singleton();
}
LeaveCriticalSection(&cs);
}
-----------------------------------*/
return single;
}
static singleton *release_singleton()
{
if (single != NULL)
{
delete single;
single = NULL;
}
}
static void print()
{
cout << "singleton print test" << endl;
}
private:
static singleton* single;
static int count;
};
singleton* singleton::single = NULL;
int singleton::count = 0;
void main01()
{
singleton* ps1 = singleton::get_singleton();
singleton* ps2 = singleton::get_singleton();
if (ps1 == ps2)
{
cout << "the same" << endl;
}
else
{
cout << "diffence" << endl;
}
}
void myfunc(void *)
{
//cout << "線程函數開始" << endl; 不會清空緩衝區
cout << "線程函數開始\n";
singleton::get_singleton()->print();
}
int _tmain(int argc, _TCHAR* argv[])
{
//main01();
//_CRTIMP uintptr_t __cdecl _beginthread (_In_ void (__cdecl * _StartAddress) (void *),
//_In_ unsigned _StackSize, _In_opt_ void * _ArgList);
InitializeCriticalSection(&cs);
HANDLE hThread[10];
for (int i = 0; i < 3; i++)
{
hThread[i] = (HANDLE)_beginthread(myfunc, 0, NULL);
}
int i = 0;
for (; i < 3; i++)
{
//等待 所有子線程均運行完畢後執行下面的代碼
//INFINITE 表示 死等
WaitForSingleObject(hThread[i],INFINITE);
}
system("pause");
return 0;
}