Ice中Monitor的使用

工程師WWW發表於2016-10-17
IceUtil::Monitor類
[cpp] view plain copy
  1. namespace IceUtil {  
  2. template <class T>  
  3. class Monitor {  
  4. public:  
  5.   void lock() const;  
  6.   void unlock() const;  
  7.   bool tryLock() const;  
  8.   void wait() const;  
  9.   bool timedWait(const Time&) const;  
  10.   void notify();  
  11.   void notifyAll();  
  12.   typedef LockT<Monitor<T> > Lock;  
  13.   typedef TryLockT<Monitor<T> > TryLock;  
  14. };  
  15. }  

1. 從程式碼可以看出,Monitor比Mutex(互斥體)多了wait/timedWait,notify/notifyAll操作。這樣允許一個獲得鎖進入臨界區的執行緒,能夠自我掛起,讓出臨界區。

2.Monitor是個模板類,需要Mutex/RecMutex(遞迴互斥體)做為模板引數。

3.wait/timedWait在等待期間,會掛起執行緒,讓出互斥體,等待被喚醒。

區別是:

timedWait(const Time&)會在時間到達後,自我喚醒,重新嘗試獲得鎖;

wait()是等待被喚醒(其他執行緒呼叫notify()或者notifyAll()。

timedWait返回值:如果有另外的執行緒呼叫 notify 或 notifyAll,在發生超時之前喚醒掛起的執行緒,這個呼叫返回 true,監控器重被鎖住,掛起的執行緒恢復執行。而如果發生超時,函式返回 false。

使用例項

[cpp] view plain copy
  1. template<class T> class Queue  
  2. public IceUtil::Monitor<IceUtil::Mutex> {  
  3. public:  
  4. void put(const T & item) {  
  5. IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);  
  6. _q.push_back(item);  
  7.   notify();  
  8. }  
  9. T get() {  
  10.   IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);  
  11.   while (_q.size() == 0)  
  12.     wait();  
  13.   T item = _q.front();  
  14.   _q.pop_front();  
  15.   return item;  
  16. }  
  17. private:  
  18.   list<T> _q;  
  19. };  

timedWait:時間到達後,嘗試獲取鎖,但可能其他執行緒正在使用,當鎖被釋放時,才會真正得到,開始後續的執行。

[cpp] view plain copy
  1. .....  
  2. IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);  
  3. if ( queue_.empty() || queue_.size() < buffer_size_ ) {  
  4.   IceUtil::Time time = IceUtil::Time::seconds( 10 );//等待10s  
  5.   timedWait(time);  
  6. }  
  7. ...  

補:

Mutex為簡單互斥體:一個執行緒獲得鎖後,不能再嘗試獲得鎖。

RecMutex為遞迴互斥體,一個執行緒可以多次嘗試獲得鎖。

相關文章