設計模式 C 單例及執行緒安全

2021-08-18 16:40:11 字數 2665 閱讀 8777

(1) 單例類保證全域性只有乙個唯一的例項物件。

(2) 單例類保證只有唯一的介面獲取這唯一例項。

class singleton ;

singleton(const singleton&) = delete;

singleton& operator=(const singleton&) = delete;

~singleton() {};

public:

/* 獲取例項 */

static singleton* getinstance()

return st;

};private:

static singleton *st;

};

class singleton ;

singleton(const singleton&) = delete;

singleton& operator=(const singleton&) = delete;

~singleton() {};

public:

/* 獲取例項 */

static singleton* getinstance()

mt.unlock();

}return st;

};private:

static singleton *st;

static

std::mutex mt;

};

上述方法執行緒完全安全了嗎?答案是並沒有。因為cpu將分配記憶體和賦值操作分開執行,這樣會出現以下情況:

執行緒a:訪問st為nullptr,開始分配記憶體;

執行緒a:先為st賦值,此時st未定義;

執行緒b:訪問st不為nullptr;

執行緒b:使用了未定義的st;

執行緒a:為st分配記憶體。

當然絕對的執行緒安全還是有問題,因為c++建立物件時,會執行三步操作:

1.分配記憶體;

2.呼叫構造;

3 賦值操作;

然而現代cpu和編譯器高併發下可能會進行亂序重排操作,因而建立物件new csingleton的第2步可能會晚於第3步進行指令呼叫,因而導致出現未定義的的行為。

舉例:

執行緒a : getinstance 判斷 instance是否為空,為空則

執行緒a : 分配記憶體 此時cpu亂序指令重排,賦值操作提前

執行緒b : getinsnace 判斷instance是否為空,非空,則返回

執行緒b : 使用了未初始化的instacne 出現未定義行為。

執行緒a : 呼叫建構函式對instance初始化。

因此要解決上述問題需要引入記憶體柵欄來確保指令執行的同步性。在cpu指令重排的前提下保持資料的一致性。

c++11的單例模式的實現

class

singleton ;

singleton(const singleton&) = delete;

singleton& operator=(const singleton&) = delete;

~singleton() {};

public:

/* 獲取例項 */

static singleton* getinstance() ;

};

#include "stdafx.h"

#include

#include

#include

#include

#include

using

namespace

std;

class singleton ;

singleton(const singleton&) = delete;

singleton& operator=(const singleton&) = delete;

~singleton() {};

public:

/*static singleton* getinstance()

mt.unlock();

}static singleton st;

return st;

};*/

static singleton* getinstance() ;

void print() ;

private:

static

std::mutex mt;

//static singleton *st;

int mm;

};//ingleton* singleton::st = nullptr;

std::mutex singleton::mt;

void thread_func()

int main()

for (auto iter = vthrd.begin(); iter != vthrd.end(); iter++)

return

0;}

c++11 單例類實現

c++的單例模式及c++11對單例模式的優化

C 單例模式及執行緒安全

2.餓漢模式 3.懶漢模式 常用 設計模式 設計模式 design pattern 是一套被反覆使用 多數人知曉的 經過分類的 設計經驗的總結。為什麼會產生設計模式這樣的東西呢?就像人類歷史發展會產生兵法。最開始部落之間打仗時都是人拼人的對 砍。後來春秋戰國時期,七國之間經常打仗,就發現打仗也是有套...

單例模式及執行緒安全

單例模式即整個程序中只存在乙個例項物件,所有執行緒共用同乙個例項物件 所謂餓漢,即非常飢餓,一開始就需要食物,也就是說物件例項在編譯過程中類載入時就建立例項。public class single public static single getinstance 所謂懶漢,就是非常懶。你不讓它幹活就...

設計模式 單例模式(執行緒安全)

前言 單例模式是設計模式中比較簡單的一種,但是又因為簡單常見在面試中又是經常出現的乙個設計模式。所以必須要會啊。之前也只是會寫執行緒不安全的單例模式。單例模式 乙個類能返回物件乙個引用 永遠是同乙個 和乙個獲得該例項的方法 必須是靜態方法,通常使用getinstance這個名稱 當我們呼叫這個方法時...