c++設計模式-單例模式

單例模式:

單例模式一般會分爲:餓漢單例和懶漢單例

餓漢式: 在類加載的時候就完成初始化,所以類加載比較慢,但是獲取對象的速度是比較快的.
懶漢式:在類加載的時候不初始化,等到第一次被使用的時候才進行初始化.

餓漢式:

class Singlenton{
	private:
		Singlenton() = default;
	    ~Singlenton() = default;
	 public:
	 	static  Singlenton & getInstance();
};
Singlenton &  Singlenton::getInstance(){
		static Singlenton c;
		return c;
}

餓漢式:

class Singlenton{
    private:
        Singlenton();
        Singlenton(const Singlenton &);
    public:
    static Singlenton * getInstance();
    static Singlenton* m_instance;
};

Singlenton * Singlenton::m_instance = nullptr;

Singlenton* Singlenton::getInstance() {
    if(m_instance == nullptr){
        m_instance = new Singlenton();
    }
    return m_instance;
}

這種方案對於多線程模式並不是安全的,有可能會同時創建多個對象
那麼,我們肯定會隨之進行加鎖操作,但是在這裏的話鎖的代價過高

Singlenton* Singlenton::getInstance() {
 std::lock_guard<mutex> b(mutex_);
    if(m_instance == nullptr){
        m_instance = new Singlenton();
    }
    return m_instance;
    }

線程A沒有釋放鎖,B無法進入,第一次之後,相當於多個線程僅僅是對這個地方進行讀取,而對於多線程讀的話是沒有必要進行加鎖,對於高併發的情況下,代價及其高昂
在這裏我們可以使用雙檢查鎖

Singlenton* Singlenton::getInstance() {
 if(m_instance == nullptr){
 //在執行這一行之前,有可能多個線程同時都執行到這一步
 std::lock_guard<mutex> b(mutex_);
    if(m_instance == nullptr){
        m_instance = new Singlenton();
    }
    }
    return m_instance;
    }

//消除代價過高的問題,對於上一次的缺陷進行完善
但是仍然有問題,內存讀寫reorder可能會造成不安全的情況
線程是在指令層級進行時間片的搶奪,cpu執行指令可能並不如我們之前的預期情況執行

std::atomic<Singlenton*> Singlenton::m_instance;
Singlenton* Singlenton::getInstance() {
	Singleton * temp = m_instance.load(std::memory_order_relaxed);
	//只保證在同一個線程內,同一個原子變量的操作的執行序列不會被重排序(reorder),這種保證也稱之爲modification order consistency,但是其他線程看到的這些操作的執行序列式不同的。
	std::atomic_thread_fence(std::memory_order_acquire); //獲取內存的fence獲取存儲
 if(temp == nullptr){
 //在執行這一行之前,有可能多個線程同時都執行到這一步
 std::lock_guard<mutex> b(mutex_);
    if(temp== nullptr){
       temp = new Singlenton();
       std::atomic_thread_fence(std::memory_order_release); //釋放內存fence
       m_instance.store(temp,std::memory_order_relaxed);
    }
    }
    return m_instance;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章