c 之單例模式

2022-01-22 10:40:02 字數 2608 閱讀 3903

1 本篇主要討論下多執行緒下的單例模式實現:

首先是 double check 實現方式: 這種模式可以滿足多執行緒環境下,只產生乙個例項。

templateclass

dclsingleton

}return *value_;

}protected

: dclsingleton()

dclsingleton(

const dclsingleton &dcl) {}

private

:

static t*value_;

static

mutex mutex_;

};

但是這種實現存在除bug的隱患, 問題就在: value_ = new t; 上。《程式設計師的自我修養》上指出:

這樣的**是有問題的,問題的**在於 cpu 的亂序執行。c++裡的new 包含了兩步。

(1)分配記憶體

(2)呼叫建構函式

所以 value_ = new t;  實際上包含了三步:

(1)分配記憶體

(2)在分配記憶體的位置上呼叫建構函式  

(3)將記憶體位址賦值給 value_;

這三步中,(2), (3)兩步是可以顛倒的,也就是說,可能出現,先執行(3)這是 value_已經不為null, 當出現另乙個對getinstance的併發呼叫,if 內的 value_ != null於是返回,但是還沒有呼叫建構函式。於是使用這個指標的時候,就會導致崩潰。

這時候需要保證(2), (3)的執行順序,通常需要加上記憶體屏障,保證一定保證(2)執行完以後,再執行(3)

這裡我加上了__sync_synchronize(); 後 實現是這樣的:

static t&getinstance()

}return *value_;

}

這樣便可以既保證多執行緒環境安全,又保證不會出現上面的問題。

2. 加上記憶體屏障的示例**:dcl_single.h

#ifndef __dcl_single_h

#define __dcl_single_h#include

namespace

yl ~mutex()

public

:

void

lock()

void

unlock()

private

: pthread_mutex_t mutex_;

};class

mutexguard

~mutexguard()

private

: mutex mutex_;

};template

class

dclsingleton

}return *value_;

}protected

: dclsingleton()

dclsingleton(

const dclsingleton &dcl) {}

private

:

static t*value_;

static

mutex mutex_;

};template

t* dclsingleton::value_ =null;

template

mutex dclsingleton

::mutex_;

}#endif

view code

singletontest.cpp

#include "

dcl_single.h

"#include

namespace

yl ~mgrsg()

public

:

void

print()

};}int

main(

void

)

3. 還可以用 unix 下的 pthread_once 來實現單例模式:

template class

mysingleton

protected

: mysingleton() {}

mysingleton(

const mysingleton&) {}

private

:

static

void

init()

private

:

static

pthread_once_t ponce_;

static t *instance;

};template

pthread_once_t mysingleton

::ponce_ =pthread_once_init;

template

t *mysingleton::instance =nullptr;

}

5. 水平有限,望及時指出錯誤。謝謝

C 之單例模式

1 c 單例模式的概念及作用 單例模式也稱為單件模式 單子模式,可能是使用最廣泛的設計模式。其意圖是保證乙個類僅有乙個例項,並提供乙個訪問它的全域性訪問點,該例項被所有程式模組共享。2 單例模式的實現原理 1 私有靜態指標變數實現 使用類的私有靜態指標變數指向類的唯一例項,並用乙個公有的靜態方法獲取...

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

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

單例模式 之 單例模式 Holder

之前我寫過 單例模式中的餓漢模式和懶漢模式 他們雖然都能實現單例模式 但是優缺點很明顯 餓漢模式 不能懶載入 類載入就會被例項化 消耗很大,在併發情況下安全性很高。懶漢模式 能實現懶載入,但是在併發情況下安全性不是很高。雖然一步一步的優化,安全性得到了保證,但是卻使用了synchronized 對效...