muduo網路庫學習筆記(6):單例類(執行緒安全的)
muduo用pthread_once實現了執行緒安全的Singleton。
檔名:Singleton.h
template<typename T>
class Singleton : boost::noncopyable
{
public:
static T& instance()
{
pthread_once(&ponce_, &Singleton::init);
return *value_;
}
private:
Singleton();
~Singleton();
static void init()
{
value_ = new T();
}
static pthread_once_t ponce_;
static T* value_;
};
template<typename T>
pthread_once_t Singleton::ponce_ = PTHREAD_ONCE_INIT;
template<typename T>
T* Singleton<T>::value_ = NULL;
使用方法也很簡單:
Foo& foo = Singleton<Foo>::instance();
其中有哪些知識點呢?
(1)瞭解單例模式
實際應用中,有些物件,我們只需要一個就可以了,比如,一臺計算機上可以連好幾個印表機,但是這個計算機上的列印程式只能有一個,這裡就可以通過單例模式來避免兩個列印作業同時輸出到印表機中,即在整個的列印過程中只有一個列印程式的例項。
單例模式是一種常用的軟體設計模式。在它的核心結構中只包含一個被稱為單例的特殊類。通過單例模式可以保證系統中一個類只有一個例項。
(2)pthread_once
#include <pthread.h>
int pthread_once(pthread_once_t *once_control,
void (*init_routine)(void));
pthread_once_t once_control = PTHREAD_ONCE_INIT;
本函式使用初值為PTHREAD_ONCE_INIT的once_control變數保證init_routine()函式在本程式執行序列中僅執行一次,且能保證執行緒安全。(我們還能用互斥鎖的方式來實現執行緒安全,但效率沒有pthread_once高)
(3)atexit
// atexit()函式用來註冊程式正常終止時要被呼叫的函式
// 在一個程式中最多可以用atexit()註冊32個處理函式
// 這些處理函式的呼叫順序與其註冊的順序相反
// 即最先註冊的最後呼叫,最後註冊的最先呼叫
#include<stdlib.h>
int atexit(void (*func)(void)); // 登記的函式型別為不接受任何引數的void函式
在Singleton.h中,atexit函式被用於註冊一個銷燬函式,在程式結束的時候會自動呼叫銷燬函式,就不用手動呼叫了。
(4)typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
在C++中,型別有Complete type和Incomplete type之分,對於Complete type, 它的大小在編譯時是可以確定的,而對於Incomplete type, 它的大小在編譯時是不能確定的。
用delete刪除一個只有宣告但無定義的型別的指標(即不完整型別),是危險的。這通常導致無法呼叫解構函式(包括物件本身的解構函式、成員/基類的解構函式),從而洩露資源。
而通過 typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1]; 這種做法能使當T為不完整型別時編譯報錯。(當T為不完整型別時,sizeof(T)給出的是0,根據程式碼規則,-1是不能作為陣列的size的,因此,這裡相當於強制編譯器給出error而不是 warning)
相關文章
- muduo網路庫學習筆記(7):執行緒特定資料筆記執行緒
- muduo網路庫學習筆記(5):執行緒池的實現筆記執行緒
- muduo網路庫學習筆記(1):Timestamp類筆記
- muduo網路庫學習筆記(3):Thread類筆記thread
- muduo網路庫學習筆記(8):高效日誌類的封裝筆記封裝
- muduo網路庫學習筆記(12):TcpServer和TcpConnection類筆記TCPServer
- muduo網路庫學習筆記(2):原子性操作筆記
- muduo網路庫學習之muduo_http 庫涉及到的類HTTP
- muduo網路庫學習筆記(11):有用的runInLoop()函式筆記OOP函式
- muduo網路庫學習筆記(14):chargen服務示例筆記
- muduo網路庫學習之muduo_inspect 庫涉及到的類
- muduo網路庫學習筆記(13):TcpConnection生命期的管理筆記TCP
- muduo網路庫學習筆記(10):定時器的實現筆記定時器
- muduo網路庫學習之EventLoop(二):程式(執行緒)wait/notify 和 EventLoop::runInLoopOOP執行緒AI
- muduo網路庫學習筆記(9):Reactor模式的關鍵結構筆記React模式
- 執行緒安全的單例模式執行緒單例模式
- muduo網路庫學習筆記(4):互斥量和條件變數筆記變數
- iOS執行緒學習筆記iOS執行緒筆記
- 多執行緒學習筆記執行緒筆記
- muduo網路庫學習之EventLoop(四):EventLoopThread 類、EventLoopThreadPool 類OOPthread
- muduo網路庫Timestamp類
- Java 多執行緒學習筆記Java執行緒筆記
- java學習筆記--多執行緒Java筆記執行緒
- Java學習筆記之執行緒Java筆記執行緒
- 多執行緒學習筆記 (轉)執行緒筆記
- Java 多執行緒學習筆記(三)-守護執行緒Java執行緒筆記
- C++ 執行緒安全的單例模式C++執行緒單例模式
- muduo網路庫Exception異常類Exception
- Linux程式執行緒學習筆記Linux執行緒筆記
- Python學習筆記 - 多執行緒Python筆記執行緒
- Java多執行緒學習筆記(自用)Java執行緒筆記
- C#多執行緒學習筆記C#執行緒筆記
- java學習筆記.04——執行緒池Java筆記執行緒
- muduo網路庫學習筆記(15):關於使用stdio和iostream的討論筆記iOS
- struts2學習筆記–執行緒安全問題小結筆記執行緒
- Java 多執行緒 學習筆記(二)停止執行緒的幾種方法Java執行緒筆記
- Redis基礎知識(學習筆記6--執行緒IO模型)Redis筆記執行緒模型
- muduo網路庫學習之Timestamp類、AtomicIntegerT 類封裝中的知識點封裝