大家好,今天书接上回,接着进行简单连接池的实现!https://blog.youkuaiyun.com/csdddd55/article/details/148928680?spm=1001.2014.3001.5501

连接池
生产连接的线程(生产者线程)
//线程生产函数
void ConnectionPool::produceconnections() {
while (true) {
unique_lock<mutex> lock(_queueMutex);//进来便加锁(这是互斥访问)
//不为空就不生产,等待
while (!_pool.empty()) {
_Empty.wait(lock);
}
//未达最大连接数,生产连接
if (_currentSize < _maxSize) {
//生产连接,放入连接池
Connection* conn=new Connection();
conn->connect(_ip, _port, _username, _password, _dbname);
//只要连接进入连接池就要重置空闲时间
conn->resetFreeTime();
_pool.push(conn);
_currentSize++;
}
//通知消费线程
//同步作用
_Empty.notify_all();
}
}
消费连接的线程(消费者线程)
//获得线程的接口实现
shared_ptr<Connection> ConnectionPool::getConnection() {
unique_lock<mutex> lock(_queueMutex);
while (_pool.empty()) {//队列为空,没有可用连接,当然就是再wait
//队列没有可用conn那就等待
if (cv_status::timeout == _Empty.wait_for(lock, chrono::milliseconds(_ConnectionTimeOut))) {
//这里将timeout和wait_for返回值进行比对是个细节,因为只有时间真得超时了才来看看是不是
//队列空了,进而判断是否报错
//如果是中间未超时,醒来,但是被其他线程抢走了资源,则不算超时报错,这个if就是防止
//这个情况发生
if (_pool.empty()) {
LOG("wait for connection timeout");
return nullptr;
}
}
}
//智能指针出了作用域就会释放,但是是直接delete
//我们希望它被delete吗?当然不啊,因为我们还要把它放回连接池呢
//所有需要自定义deleter,那就是用lamada函数进行
//不了解lamada就去学习一下,这里不展开叙述,不是很难
shared_ptr<Connection> conn(_pool.front(), [&](Connection* p) {
//访问队列就要互斥访问
unique_lock<mutex> lck(_queueMutex);
_pool.push(p);
p->resetFreeTime();
});
_pool.pop();
//消费了就唤醒生产者线程,反正它执不执行也会判断
_Empty.notify_all();
return conn;
}
注意看代码里的注意奥,里面有详细解释,我在外面就不过多赘述了。感谢理解
清理线程
//清理线程
void ConnectionPool::cleanconnections() {
while (true) {
//当然我们没必要每时每刻都在扫描,每过最大空闲时间扫描一次即可
this_thread::sleep_for(chrono::seconds(_maxIdleTime));
//老话畅谈:共享资源访问互斥访问
unique_lock<mutex> lock(_queueMutex);
//只有当前连接数量多于初始连接量才会出发这个被动(清理)
while (_cur

最低0.47元/天 解锁文章
669

被折叠的 条评论
为什么被折叠?



