项目中经常会遇到这个的问题:
从连接池中获取的连接,忘记放进连接池了;
加锁后,忘记解锁了
。。。
这个是时候,你可能会想,有谁能帮我,在我获取的资源不用的时候,给删除掉,免得我自己来亲力亲为。
有的,C++11已经提供了对锁的自动释放,很简单:
#include<mutex>
std::mutex mutex_;
std::unique_lock<std::mutex> lock(mutex_);
在lock出作用域的时候,会自动调用mutex_的ulook()函数,就不用自己来解锁。
利用上面的思想,对自己获取的连接池资源进行智能释放:
class AutoMgrConn{
public:
explicit AutoMgrConn(CacheConnPool& connPool) : connPool_(connPool) {};
CacheConn* GetConn(uint64_t waitTime) {
cacheConn_ = connPool_.GetConn(waitTime = 0);
return cacheConn_;
}
~AutoMgrConn() {
connPool_.RetConn(cacheConn_);
}
private:
CacheConn* cacheConn_;//从连接池中获得的连接(将要智能管理的)
CacheConnPool& connPool_;//连接池
};
有了上面的类,就可以获得一个连接,然后肆意的玩耍,不用去管怎么释放。
CacheConn* cacheConn = AutoMgrConn().GetConn() //获取一个连接 出作用域自动释放
本以为写成这样就可以了,但是棋哥提醒,返回智能指针,自定制智能指针的删除器。哇呜还可以这么玩,好吧,继续努力!
void CacheConnPool::RetConn_(CacheConn* cacheConn) {
std::unique_lock<std::mutex> lock(connPoolmutex_);
//...do something
LOG_DEBUG << "release connect succ!";
conditionVariable_.notify_one();//通知一个在等待的线程去获取连接资源
}
std::shared_ptr<CacheConn> CacheConnPool::GetConn(uint64_t waitTime /*= 0*/) {
//...do something
std::function<void(CacheConn*)> function = std::bind(&CacheConnPool::RetConn_, this, std::placeholders::_1);
std::shared_ptr<CacheConn> cacheConnPtr(cacheConn, function); return cacheConnPtr;
}
嗯,就是这样,返回一个智能指针,这个智能指针在出作用域的时候会调用RetConn_函数,即自动调用了释放函数!