C 11多執行緒單例設計模式共享資料處理

2021-09-12 02:37:02 字數 4367 閱讀 5558

**

僅僅是學習設計模式而不用於實際,很快會忘記。從專案中學習處理複雜問題的方法,將之總結為設計模式才是正道。

某些情況下,我需要某個類只被例項化一次,用了一次就不能再被例項化。

這樣的類就叫做單例類。

私有化建構函式 ------- 保證不能隨意的建立類物件

私有化乙個靜態成員變數 -------- 做有沒有例項化過的標誌,保證只例項化一次

公開的靜態成員函式介面 ------ 建立類物件的介面

#include

#include

#include

#include

#include

#include

using

namespace std;

//單例類 只能生成乙個物件

class

mycas

static mycas* s_instance;

//靜態成員變數

public

://靜態成員函式介面

static mycas*

getinstance()

return s_instance;

}void

func()

};//初始化靜態變數

mycas* mycas::s_instance =

null

;void

test01()

intmain()

在公開的靜態介面內建立物件的模式為懶漢式模式,還可以把建立物件寫在類外(餓漢式),後一種保證了之後無論是不是多執行緒,無論怎麼訪問。靜態介面都只會返回靜態變數,實際用起來再看看。

餓漢式:

class

mycas

static mycas* s_instance;

//靜態成員變數

public

://靜態成員函式介面

static mycas*

getinstance()

void

func()

};//初始化靜態變數

mycas* mycas::s_instance =

newmycas()

;

如果想自己釋放單例類的靜態變數的記憶體,千萬不要寫下面這樣的成員方法:

static

void

freespace()

}

一般使用單例都是在多執行緒中使用的,如果在一邊被釋放,另一邊還要用就會產生問題了。

所以,不要手動釋放單例的記憶體。

如果想釋放,需要憑藉巢狀類可以訪問類中私有變數的方法:

在單例類中寫乙個巢狀類,宣告定義乙個巢狀類的靜態變數--------這個變數的生命週期會一直到程式退出時--------當程式退出,巢狀類的析構被執行到,在析構中把單例的靜態變數記憶體刪除。

class

garbo}}

;

將下面這個隨便寫在單例類**。

static garbo garbo;
多執行緒中使用單例模式的示例**:

#include

#include

#include

#include

#include

#include

using

namespace std;

//單例類 只能生成乙個物件

class

mycas

static mycas* s_instance;

//靜態成員變數

public

://靜態成員函式介面

static mycas*

getinstance()

return s_instance;

}/*巢狀類*/

class

cgarrelease}}

;/*巢狀類完*/

void

func()

};//初始化靜態變數

mycas* mycas::s_instance =

null

;//執行緒入口函式

void

myprint()

/*共享資料分析

1.單例初始化一般在建立執行緒之前

2.多執行緒需要讀寫單例時,需要在子執行緒中建立單例類物件

*/void

test02()

intmain()

為了提高程式效率,不能總是使用一次getinstance()就給執行緒加一把鎖,而是只在第一次建立類物件時有加鎖。

解決方案是在加鎖前,再判斷一次!!!

static mycas*

getinstance()

}return s_instance;

}

第乙個條件判斷的意思是,某個執行緒例項化後,其他執行緒和此執行緒都不應該再進入了。

那麼為什麼裡面還要再判斷一次呢?

第二個條件判斷的意思是,第一次例項化時,好幾個執行緒一同進入加鎖的位置,如果沒有第二個條件,那麼就不能避免重複建立類物件。

std::call_once()類模板 第二個引數是函式名a

功能:保證函式a只被呼叫一次

特徵:具備互斥量的能力

使用方式:和std::once_flag()這個標記配合使用

std::call_flag()呼叫成功後,標記std::once_flag就會被設定為「已呼叫」狀態,那麼函式a就不會執行了。

#include

#include

#include

#include

#include

#include

using

namespace std;

mutex resource_mutex;

std::once_flag g_flag;

//系統定義的標記

//單例類 只能生成乙個物件

class

mycas

private

://私有化建構函式

mycas()

static mycas* s_instance;

//靜態成員變數

public

://靜態成員函式介面

static mycas*

getinstance()

return s_instance;

}/*巢狀類*/

class

cgarrelease}}

;/*巢狀類完*/

void

func()

};//初始化靜態變數

mycas* mycas::s_instance =

null

;//執行緒入口函式

void

myprint()

void

test02()

intmain()

1.函式a為std::call_once()所使用到的函式(呼叫自身)

#include

#include

#include

using

namespace std;

std::once_flag g_flag;

void

do_once1()

);}void

test01()

呼叫自身使用的是lambda表示式,也可以寫成下面這樣:

void

do_once1()

; std::

call_once

(g_flag,my_lambda)

;}

2.函式a內還有std::call_once()呼叫函式b

#include

#include

#include

using

namespace std;

std::once_flag g_flag;

inline

void

may_throw_function

(bool do_throw)

cout <<

"once\n";}

inline

void

do_once

(bool do_throw)

//catch(...)

}void

test02()

intmain()

多執行緒 多執行緒 單例設計模式

多執行緒之 單例設計模式 餓漢式 多執行緒安全 1 餓漢式 class single static single getinstance public void show class a implements runnable class test catch interruptedexceptio...

單例設計模式下的多執行緒資料共享 C

include include include using namespace std mutex resource mutex 增加互斥量 once flag g flag 系統定義的標記 較實用的單例類 class mycas private static mycas m instance 靜態...

c 多執行緒單例模式 C 設計模式之單例模式

單例模式 乙個類在記憶體中只有乙個物件 例項 並且提供乙個可以全域性訪問或者獲取這個物件的方法。這兩天學的,寫了個小例子,問了同事一些關於執行緒的問題,還有從網上查了一些資料。還犯了一些低階的錯誤。vs2017控制台輸出文字亂碼,從網上找了一些方法不管用,最後發現是自己新建專案選錯模板了,選擇了.n...