智能锁

在进行智能锁之前,需要了解一下什么叫 锁,参考http://konin.iteye.com/blog/2333350

啥叫智能锁呢,就是我在想锁住资源的时候,就锁住,待资源使用完后,自动释放该锁,比如

 

{//锁生命周期开始
 LockGuard<InfoOrderQueue> guard(m_queue);//加锁
}//锁生命周期结束,自动释放锁

 

上面这段代码中,m_queue是InfoOrderQueue类型的资源,需要加锁,LockGuard是智能锁,当生命周期结束的时候,自动释放锁,就是这么个道理,那么如何实现呢?

 

先说明一下,为什么会做到自动加锁,是因为LockGuard的构造函数里,调用了InfoOrderQueue类的接口进行加锁,也就是说,资源本身自带了锁功能,而LockGuard的作用仅仅是做了自动加锁与释放的功能,具体的加锁释放本事是在资源类里进行的。先看看  InfoOrderQueue的声明

 

es::Queue<InfoOrder> InfoOrderQueue;
 
template<class T, class Q = deque<T> >
class Queue {
public:
    //输入队列
    typedef Q ItemQueue;

    //大小类型
    typedef typename ItemQueue::size_type SizeType;

    //元素类型
    typedef T ValueType;

    /**
     * 构造函数
     * @param highWaterMark 队列高水位标, 0表示不限制
     */
    Queue(SizeType highWaterMark = 0) : _highWaterMark(highWaterMark), _lowCond(_mutex),
                                        _highCond(_mutex) {}

    /**
     * 加锁
     */
    void acquire() {
        _mutex.acquire();
    }

    /**
     * 尝试加锁
     */
    bool tryAcquire() {
        return _mutex.tryAcquire();
    }

    /**
     * 解锁
     */
    void release() {
        _mutex.release();
    }

    /**
     * 唤醒一个线程
     */
    void signal() {
        _lowCond.signal();
    }

    /**
     * 唤醒所有等待队列的线程
     */
    void broadcast() {
        _lowCond.broadcast();
    }

    /**
     * 添加输入请求到队尾, 调用者要先锁定队列
     */
    void add(T inputItem) {
        while (_highWaterMark > 0 && _queue.size() >= _highWaterMark) {
            _highCond.wait();
        }
        _queue.push_back(inputItem);
        _lowCond.signal();
    }

    /**
     * 添加批量输入请求到队尾, 调用者要先锁定队列
     */
    template<class Iterator> void add(Iterator first, Iterator last) {
        for (Iterator iter = first; iter != last; ++iter) {
            while (_highWaterMark > 0 && _queue.size() >= _highWaterMark) {
                _highCond.wait();
            }

            _queue.push_back(*iter);
            _lowCond.signal();
        }
    }

    /**
     * 获取队首元素, 调用者要先锁定队列
     */
    const T& peek() {
        while (_queue.empty()) {
            _lowCond.wait();
        }
        return _queue.front();
    }

    /**
     * 删除队首元素
     */
    void pop() {
        _queue.pop_front();

        if (_highWaterMark > 0) {
            _highCond.signal();
        }
    }

    /**
     * 获取队列元素个数
     */
    SizeType size() const {
        return _queue.size();
    }

    /**
     * 获取队列是否为空
     */
    bool empty() const {
        return _queue.empty();
    }

    /**
     * 获取高水位标
     */
    SizeType getHighWaterMark() const {
        return _highWaterMark;
    }

    /**
     * 设置高水位标
     */
    void setHighWaterMark(SizeType highWaterMark) {
        _highWaterMark = highWaterMark;
    }

    /**
     * 清空队列
     */
    void clear() {
        _queue.clear();

        if (_highWaterMark > 0) {
            _highCond.broadcast();
        }
    }

private:
    SizeType        _highWaterMark;
    ItemQueue       _queue;
    Mutex           _mutex;
    Condition       _lowCond;
    Condition       _highCond;
}; 

上面这段代码中用到了mutex,这个类的实现在开头给的连接中有介绍,Condition会在后面介绍

 

再看看LockGuard的实现

template<class LockType> class LockGuard {
public:
    /**
     * 构造函数
     */
    LockGuard(LockType& lock) : _lock(lock), _acquired(false) {
        _lock.acquire();
        _acquired = true;
    }

    /**
     * 构造函数
     */
    LockGuard(LockType& lock, bool acquired) : _lock(lock), _acquired(acquired) {
        if (!acquired) {
            _lock.acquire();
            _acquired = true;
        }
    }

    /**
     * 析构函数
     */
    ~LockGuard() {
        if (_acquired) {
            _lock.release();
        }
    }

    /**
     * 是否已经加锁
     */
    bool isAcquired() const {
        return _acquired;
    }

    /**
     * 转型
     */
    operator const void*() const {
        return _acquired ? this : 0;
    }

    /**
     * 加锁
     */
    void acquire() {
        _lock.acquire();
        _acquired = true;
    }

    /**
     * 解锁
     */
    void release() {
        _lock.release();
        _acquired = false;
    }

private:
    LockType&   _lock;
    bool        _acquired;
};

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值