muduo網路庫學習之BlockinngQueue類、ThreadPool 類、Singleton類封裝中的知識點

s1mba發表於2013-11-01

一、BlockinngQueue<T>類、BoundedBlockingQueue<T>類


生產者消費者問題,可以用訊號量+互斥鎖 或者 條件變數+互斥鎖 來解決,還分為有界和無界緩衝區兩種情形,如下圖:

有界緩衝區

生產者:
訊號量+互斥鎖:1,2,3,4,5
條件變數+互斥鎖:2,1,3,5,4(外框)

消費者:
訊號量+互斥鎖: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個步驟的集合。

template<typename T>
class BoundedBlockingQueue : boost::noncopyable

有界緩衝區:與無界緩衝區多了一個條件變數notFull成員,並且使用boost庫的環形緩衝區。

二、ThreadPool類(固定執行緒數,不考慮執行緒數動態增減)


執行緒池本質上也是生產者消費者問題:
生產者執行緒向任務佇列新增任務,消費者執行緒(線上程佇列中)從任務佇列取出任務去執行。

class ThreadPool : boost::noncopyable
typedef boost::function<void ()> Task;

程式碼中有這麼一段:

 C++ Code 
1
2
3
threads_.push_back(new muduo::Thread(
                       boost::bind(&ThreadPool::runInThread, this), name_ + id));
threads_[i].start();

初看有點奇怪,其實是因為ptr_vector<T>過載了[], 即 T& operator[]( size_type n );


三、singleton類

template<typename T>
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++網路庫》


相關文章