1. 程式人生 > >完整的C++ 靜態單例程式碼(帶互斥量Mutex)

完整的C++ 靜態單例程式碼(帶互斥量Mutex)

今天又複習了一下靜態單例,但是以前只是知道實現靜態單例的原理以及注意事項,寫的程式碼也沒有執行過,因為靜態單例涉及到了多執行緒的知識,

並且我以前 只在Linux上用C語言的多執行緒,對windows下的C++多執行緒不瞭解。

帶有多執行緒保護的靜態單例原理我不細講,網上一大堆,能執行的程式碼 我沒找到(或者 我感覺那程式碼很亂,不符合自己口味)

今天下決心寫一個能夠執行的 帶有多執行緒保護的(帶互斥量)的靜態單例,最主要是的 符合我的口味

程式碼如下:

#include <iostream>
#include <thread>         // std::thread 
#include <mutex>          // std::mutex
using namespace std;

/*用互斥量構建一個枷鎖類*/
class Lock{
private:
	mutex mtx;//互斥量
public:
	void lock(){ mtx.lock(); }//加鎖
	void unlock(){ mtx.unlock(); }//解鎖
};
/*靜態單例*/
class singleton{
private:
	int _value;//測試用值,靜態單例在哪個執行緒中被第一次獲取,_value的值就是哪個執行緒的id
	singleton(int value);//建構函式
	singleton(const singleton &);//複製建構函式
	singleton& operator=(const singleton &);//賦值建構函式
public:
	static Lock* Locker;//宣告一個枷鎖指標
	static singleton* Instance;//宣告一個物件

	static singleton* getInstance(int thread_id);//宣告獲取單例的函式
	int getValue();//獲取測試值
	~singleton();//解構函式
};

singleton::singleton(int value) :_value(value){}//建構函式
singleton::singleton(const singleton &){}//複製建構函式
singleton& singleton::operator=(const singleton &){ return *this; }//賦值建構函式
singleton::~singleton(){}//解構函式

Lock* singleton::Locker = new Lock();//初始化靜態單例中的枷鎖
singleton* singleton::Instance = NULL;//初始化靜態單例

singleton* singleton::getInstance(int thread_id){//定義獲取單例的函式
	if (Instance == NULL){//由於加鎖比較費事,所以先判斷一次
		Locker->lock();
		if (Instance == NULL){
			Instance = new singleton(thread_id);//初始化靜態單例,引數為 執行緒的id
		}
		Locker->unlock();
	}
	return Instance;
}
int singleton::getValue(){//獲取測試值
	return _value;
}

mutex myMtx;//為了防止多個執行緒爭奪 標準輸出資源而設定的互斥量
void print_thread_id(int thread_id){//執行緒函式
	singleton* Instance = singleton::getInstance(thread_id);//獲取靜態單例
	myMtx.lock();
	cout << "thread_id: " << thread_id << endl;
	cout << "Instance is Created in thread: " << Instance->getValue() << endl;
	myMtx.unlock();
}

int main(){
	thread threads[2];//兩個執行緒
	int i;
	for (i = 0; i < 2; ++i)
		threads[i] = thread(print_thread_id, i);//啟動執行緒

	for (auto& th : threads) th.join();//等執行緒結束
	return 0;
}
執行結果如下:說明 靜態單利是線上程0中被建立的,也證明執行緒1中的物件與執行緒0中的物件是同一個!


注意:互斥量mutex是在c++11中才有的,這個程式碼是我在 Visual Studio 2013 上編寫的!!!

有什麼問題歡迎大家留言討論

--------------------------------------------------

解釋一下 “單例模式唯一例項為什麼必須為靜態”:

你只要弄明白單例模式是如何實現的,就能從本質上理解這個問題;
單例模式實現過程如下:
  首先,將該類的建構函式私有化(目的是禁止其他程式建立該類的物件);
  其次,在本類中自定義一個物件(既然禁止其他程式建立該類的物件,就要自己建立一個供程式使用,否則類就沒法用,更不是單例);
  最後,提供一個可訪問類自定義物件的類成員方法(對外提供該物件的訪問方式)。

直白的講就是,你不能用該類在其他地方建立物件,而是通過該類自身提供的方法訪問類中的那個自定義物件


那麼問題的關鍵來了,程式呼叫類中方法只有兩種方式,

  ①建立類的一個物件,用該物件去呼叫類中方法;

  ②使用類名直接呼叫類中方法,格式“類名::方法名()”;
上面說了,建構函式私有化後第一種情況就不能用,只能使用第二種方法。
而使用類名直接呼叫類中的方法類中方法必須是靜態static的,而靜態方法不能訪問非靜態成員變數,因此類自定義的例項變數也必須是靜態的
這就是單例模式唯一例項必須設定為靜態的原因。~~~

相關推薦

完整C++ 靜態程式碼互斥Mutex

今天又複習了一下靜態單例,但是以前只是知道實現靜態單例的原理以及注意事項,寫的程式碼也沒有執行過,因為靜態單例涉及到了多執行緒的知識, 並且我以前 只在Linux上用C語言的多執行緒,對windows下的C++多執行緒不瞭解。 帶有多執行緒保護的靜態單例原理我不細講,網上

c++實現懶漢與餓漢

 懶漢與餓漢   單例大約有兩種實現方法:懶漢與餓漢。 懶漢:故名思義,不到萬不得已就不會去例項化類,也就是說在第一次用到類例項的時候才會去例項化,所以上邊的經典方法被歸為懶漢實現;餓漢:餓了肯定要飢不擇食。所以在單例類定義的時候就進行例項化。   特點與選擇: 由於要進行執行緒同步,所以在訪問量

C++實現模式包括採用C++11中的智慧指標

    對於設計模式來說,以前只是看過基礎的理論,很多都沒有實現和使用過。這段時間看到了別人C++程式碼中使用了單例模式,發現了很多新的東西,特此總結記錄一下。說話比較囉嗦,希望由淺入深,幫助大家理解!     單例模式,顧名思義,即一個類只有一個例項物件。C++一般的方法

【wif 系列】C#之模式Singleton最佳實踐

com value 快捷 lock 詳細介紹 筆記本 改進 奇怪 我不知道 目錄 介紹 第一個版本 ——不是線程安全的 第二個版本 —— 簡單的線程安全 第三個版本 - 使用雙重檢查鎖定嘗試線程安全 第四個版本 - 不太懶,不使用鎖且線程安全 第五版 - 完全懶惰的實例化

C++實現一個模式懶漢與餓漢

單例模式的特點: 1、一個類只能有一個例項。 2、一個類必須自己建立自己的唯一例項。 3、一個類必須給所有其他物件提供這一例項。 單例模式的實現: 1、將建構函式宣告為private防止被外部

模式懶漢,餓漢

ati turn 還需 sin 有用 只需要 對象 clas main Java中的單例模式一般分為懶漢模式和餓漢模式,懶漢模式只有用得到的時候對象才初始化,餓漢模式無論用得到與否,都先初始化。 懶漢模式在運行的時候獲取對象比較慢(因為類加載時並沒有創建對象實例),但是加載

java模式雙重檢查加鎖的原因

csharp sta get 第一次 instance new 同步機制 原因 AR public class Singleton{ private static Singleton instance = null;//是否是final的不重要,因為最多只可能實

模式餓漢式 & 懶漢式

建立型模式——單例模式 -目的:使得類的一個物件成為該類系統中的唯一例項。 -定義:一個類有且僅有一個例項,並且自行例項化向整個系統提供。 優點: 1、在記憶體中只有一個物件,節省記憶體空間。 2、

高併發下執行緒安全的模式最全最經典

在所有的設計模式中,單例模式是我們在專案開發中最為常見的設計模式之一,而單例模式有很多種實現方式,你是否都瞭解呢?高併發下如何保證單例模式的執行緒安全性呢?如何保證序列化後的單例物件在反序列化後任然是單例的呢?這些問題在看了本文之後都會一一的告訴你答案,趕快來閱讀吧! 什麼

高併發環境下執行緒安全的模式最全最經典

在所有的設計模式中,單例模式是我們在專案開發中最為常見的設計模式之一,而單例模式有很多種實現方式,你是否都瞭解呢?高併發下如何保證單例模式的執行緒安全性呢?如何保證序列化後的單例物件在反序列化後任然是單例的呢?這些問題在看了本文之後都會一一的告訴你答案,趕快來閱讀吧!什麼是單

Java 模式餓漢+懶漢

java單例就是一個類始終只例項化一次 餓漢模式:在程式啟動,類載入的時候就初始化: public class Singleton{ private static Singleton instance = new Singleton(); private S

C語言】通訊錄程式碼一個檔案下實現

//【C語言】通訊錄(一個檔案實現)#include <stdio.h> #include <string.h> #define NAME_MAX 20 #define SEX_MAX 5 #define TEL_MAX 11 #define ADD

錯誤的模式飽漢餓漢

所謂單例模式就是同一時間只能初始化一個類物件, 所以,私有化構造方法,然後提供例項化類的方法。程式碼如下: class SingleObject1 {          //餓漢式單例模式    private SingleObject1() {}  public s

設計模式之模式C++程式碼實現

1、單例模式: 單例模式:用來建立獨一無二的,只能夠有一個例項的物件。 單例模式的結構是設計模式中最簡單的,但是想要完全實現一個執行緒安全的單例模式還是有很多陷阱的。 2、應用場景: 共享資料或者共享訪問點; 建立一個物件需要消耗的資源過多,如訪問IO和

C#設計模式之一模式Singleton Pattern【創建型】

nal 設計 類庫 開發 避免 sum behavior 並且 負責 原文:C#設計模式之一單例模式(Singleton Pattern)【創建型】一、引言 看了李建忠老師的講的設計模式已經有一段時間了(這段時間大概有一年多了),自己還沒有寫過自己的、有關設計模

Android設計模式 模式靜態內部類模式

DCL雖然在一定程度上解決了資源消耗、多餘的同步、現成安全問題,但是還是在某些情況下會出現失效問題。成為雙重檢查鎖定(DCL)失效。 建議使用如下程式碼: package demo; publ

C++面試 設計模式之模式C++11

單例模式 確保一個類只有一個例項,並提供了一個全域性訪問點。 單例模式,可以說設計模式中最常應用的一種模式了,據說也是面試官最喜歡的題目。但是如果沒有學過設計模式的人,可能不會想到要去應用單例模式,面對單例模式適用的情況,可能會優先考慮使用全域性或者靜態變數

c++中的 模式singleton和雙檢測鎖Double-Checked Locking

今天學習了一下c++中的singleton。google了一篇論文C++ and the Perils of Double-Checked Locking。大名鼎鼎的Scott Meyers寫的。論文使用c++講解,看了之後受益匪淺。 巧的是,讀完之後剛好看見http://

C++的模式與執行緒安全模式懶漢/餓漢

單例模式 單例模式:是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個例項。即一個類只有一個物件例項。   實現簡單的單例模式:建構函式宣告為private或protect防止被外部函式

BoolanC++設計模式 <九> ——模式Singleton和享元模式FlyWeight

“物件效能”模式 面向物件很好的解決了“抽象”的問題,但是必不可免地要付出一定的代價。對於通常情況來講,面向物件的成本大都可以忽略不計。但是某些情況,面向物件所帶來的成本必須謹慎處理。 典型模式Sington Flyweight 單例模式Singleton 保證一個類僅有一個例項,並