singleton中的陷阱

2021-07-09 22:01:59 字數 1212 閱讀 1160

單件模式應該是設計模式中運用得最多的模式之一,對於全域性性的復用性的物件我們通常會採用單件模式,正是因為單件這種頻繁運用的看似簡單的模式前段時間在我們的專案中卻引發了乙個致命性的崩潰bug,因此在這裡總結一下,希望能給大家有所幫助。所謂單件模式就是在整個程序執行期間只需要例項化一次為所有執行執行緒公用的物件。正因為單件可以為多個執行緒共用所以我們必須要保證它的執行緒安全性。通常實現單件有兩種方式

方式一:

`class singnton

return s_instance;

}static

void releaseinstance()

private:

singleton():s_instance(null){}

~singleton(){}

static singleton* s_instance;

}

方式二:

class singnton

private:

singleton():s_instance(null){}

~singleton(){}

static singleton* s_instance;

}

還有第三種方式就是通過全域性靜態變數來實現,但是這種方式相比以上兩種不具有lazy特性(延遲初始化),因此一般不推薦使用,

我們首先看第一種方式,通過在heap上例項化物件來實現,這種方式必須要在程序退出之前手動釋放heap上分配的記憶體,看似要麻煩一些。第二種是通過宣告乙個區域性靜態變數在static-global區域上例項化乙個物件,由於該變數例項化在靜態全域性區域,所以我們不需要關心其記憶體釋放問題。因為靜態全域性區域是在程式退出之時由作業系統自己**的。好的,看起來第二種方式顯然更方便一些。我們不用管理麻煩的記憶體釋放問題。但是有時第二種方式會導致很奇怪的bug,比如如果你在乙個執行緒中使用該單件類,在程序退出時做一些清理操作,由於靜態全域性區域的不可控性,此時該程序的靜態全域性區域有可能已被作業系統釋放清理該靜態變數因此已被釋放,但是你的其他執行緒中可能還在用該靜態變數這樣傳出去的指標已經成了懸浮指標(野指標)會導致嚴重的記憶體錯誤!!!正是由於全域性靜態區域生命期的不可控性導致了這種奇怪的難以察覺的bug.因此我們在實現單件類時通常採用第一種方式,即使麻煩些,但是我們能準確控制該變數記憶體的生命期(在確定已經處理完後呼叫releaseinstance釋放該heap區域即可),這樣就不會出現在程式退出時出現的奇怪的崩潰bug了(一般是多執行緒中才會出現)。

Method Swizzling中的陷阱

這篇文章不是介紹什麼是方法交換,這類文章很多,如果你不知道什麼是方法交換可以看這篇文章 method swizzling 方法交換是很危險的東西,會產生一些未知的錯誤,最近在使用方法交換時就遇到了這樣的問題,在我交換了乙個系統方法後,在呼叫這個方法時會在我交換的方法中迴圈無法跳出。最終我找到了問題的...

列表中的陷阱

列表是python中常用的一種資料結構,能夠存放任意的其他資料型別,int str list tuple等,但是最近發現了乙個問題,如下 data buff dict for i in range 5 buff d i print data 原本以為列印的結果會是 但是最終的結果為 最後發現其實當我...

列表中的陷阱

列表是python中常用的一種資料結構,能夠存放任意的其他資料型別,int str list tuple等,但是最近發現了乙個問題,如下 data buff dict for i in range 5 buff d i print data 原本以為列印的結果會是 但是最終的結果為 最後發現其實當我...