一、BlockinngQueue<T>類、BoundedBlockingQueue<T>類
生産者消費者問題,可以用信号量+互斥鎖 或者 條件變量+互斥鎖 來解決,還分為有界和無界緩沖區兩種情形,如下圖:

有界緩沖區:
生産者:
信号量+互斥鎖:1,2,3,4,5
條件變量+互斥鎖:2,1,3,5,4(外框)
消費者:
無界緩沖區:
信号量+互斥鎖:2,3,4,5
條件變量+互斥鎖:2,3,5,4(外框)
信号量+互斥鎖:1,2,3,4
條件變量+互斥鎖:2,1,3,4(外框)
template<typename T>
class BlockingQueue : boost::noncopyable
無界緩沖區:使用條件變量+互斥鎖實作,put()可以看作是生産者,take()可以看作實作消費者,内部的實作就是上述4個步驟的集合。
class BoundedBlockingQueue : boost::noncopyable
有界緩沖區:與無界緩沖區多了一個條件變量notFull成員,并且使用boost庫的環形緩沖區。
二、ThreadPool類(固定線程數,不考慮線程數動态增減)
線程池本質上也是生産者消費者問題:
生産者線程向任務隊列添加任務,消費者線程(線上程隊列中)從任務隊列取出任務去執行。
class ThreadPool : boost::noncopyable
typedef boost::function<void ()> Task;
代碼中有這麼一段:
初看有點奇怪,其實是因為ptr_vector<T>重載了[], 即 T& operator[]( size_type n );
三、singleton類
class Singleton : boost::noncopyable
1、pthread_once
pthread_once(&ponce_, &Singleton::init);
保證init函數隻被調用一次,即隻初始化一個對象。在init内部 value_ = new T();
2、atexit
::atexit(destroy);
在init 函數内注冊destroy,在程式結束時會調用destroy,在destroy内部delete value_;
3、typedef char T_must_be_complete_type[sizeof(T) == 0 ? -1 : 1];
假設class A; A* p; delete p; 現在A隻是前向聲明,是不完全類型,那麼delete p會出問題,但在編譯時隻是報警告。
sizeof(A) == 0; 故 typedef char T_must[-1]; 在編譯時就會出錯。
參考:
muduo manual.pdf
《linux 多線程伺服器程式設計:使用muduo c++網絡庫》