• Ice中Monitor的使用


    IceUtil::Monitor类

    namespace IceUtil {
    template <class T>
    class Monitor {
    public:
      void lock() const;
      void unlock() const;
      bool tryLock() const;
      void wait() const;
      bool timedWait(const Time&) const;
      void notify();
      void notifyAll();
      typedef LockT<Monitor<T> > Lock;
      typedef TryLockT<Monitor<T> > TryLock;
    };
    }

    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。

    使用实例

    template<class T> class Queue
    : public IceUtil::Monitor<IceUtil::Mutex> {
    public:
    void put(const T & item) {
    IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
    _q.push_back(item);
      notify();
    }
    T get() {
      IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
      while (_q.size() == 0)
        wait();
      T item = _q.front();
      _q.pop_front();
      return item;
    }
    private:
      list<T> _q;
    };


    timedWait:时间到达后,尝试获取锁,但可能其他线程正在使用,当锁被释放时,才会真正得到,开始后续的执行。

    .....
    IceUtil::Monitor<IceUtil::Mutex>::Lock lock(*this);
    if ( queue_.empty() || queue_.size() < buffer_size_ ) {
      IceUtil::Time time = IceUtil::Time::seconds( 10 );//等待10s
      timedWait(time);
    }
    ...

    补:

    Mutex为简单互斥体:一个线程获得锁后,不能再尝试获得锁。

    RecMutex为递归互斥体,一个线程可以多次尝试获得锁。

  • 相关阅读:
    虚拟机的Linux 安装 若干问题(一)
    理解JavaScript的闭包
    javascript里面的引用类型和值类型
    javascript导入自定义模块
    简单了解下CAP定理与BASE定理
    背包问题之完全背包
    背包问题之多重背包
    背包问题之0-1背包
    搜索算法初步总结
    谈一谈“回溯法“
  • 原文地址:https://www.cnblogs.com/whuqin/p/4982036.html
Copyright © 2020-2023  润新知