手写数据库连接池---C++11(下)

接上一集

创建连接的生产者线程

mutex _queueMutex; //维护连接队列的线程安全互斥锁

通过返回智能指针来控制连接的释放,当连接出作用域的时候,智能指针自动调用析构函数,此时只要修改析构函数,让他把资源归还给连接池,而不是删除就可以。

.头文件中添加 void produceConnectionTask();//运行在独立的线程中,专门负责生产新连接
源文件中实现

void ConnectionPool::produceConnectionTask()
{
   
	for (;;)
	{
   
		unique_lock<mutex> lock(_queueMutex);
		while (!_connectionQue.empty())
		{
   
			cv.wait(lock);//队列不空,此处生产线程进入等待状态
		}

		//连接数量没有到达上限,继续创建新连接
		if (_connectionCnt <  _maxSize)
		{
   
			connection* p = new connection();
			p->connect(_ip, _port, _username, _password, _dbname);
			_connectionQue.push(p);
			_connectionCnt++;
		}
		//通知消费者线程可以消费连接了
		cv.notify_all(); 
	}
}

其中 condition_variable cv;//设置条件变量,用于连接生产线程和连接消费线程的通信

生产者逻辑:
连接池非空,生产者就等待。
如果连接池空了,生产者就检查,此时连接数量是否超过了设置的最大连接数
如果没有到达上限,就创建新连接
通知消费者线程可以消费连接

消费连接的消费者线程代码实践

给外部提供接口,从连接池中获取一个可用的空闲连接
头文件添加:shared_ptr< connection> getConnection();
源文件实现:

shared_ptr<connection> ConnectionPool::getConnection()
{
   
	unique_lock<mutex> lock(_queueMutex);
	while(_connectionQue.empty())//如果队列空了,即没有连接给我使用
	{
   
		//等待最大空闲时间
		if (cv_status::timeout == cv.wait_for
		(lock, chrono::milliseconds(_connectionTimeout)))
		{
   
			if (_connectionQue.empty())
			{
   
				LOG("获取空闲连接超时了...获取连接失败!");
				return nullptr;
			}

		}

		
	}

	/*
	shared_ptr智能指针析构时,会把connection资源delete掉,相当于
	调用connection的析构函数,connection就被close掉了,这里
	需要自定义shared_ptr的释放资源方式,把connection直接归还到queue当中
	*/
	shared_ptr<connection> sp(_connectionQue.front(),
		[&](connection* pcon) {
   
			//是在服务器应用线程中调用的,所以一定要考虑队列的线程安全操作
			unique_lock<mutex> lock(_queueMutex);
			_connectionQue.push(pcon);
		});
	_connectionQue.pop();
	
	//消费了队列中最后一个connection,就要通知一下生产者连接
	cv.notify_all();

	return sp;
}

不能使用sleep来控制等待最大空闲时间
因为sleep就直接睡那么长时间了,即使有了新连接可以用,也会睡觉。

消费者逻辑:
当队列空时
---- 等待最大空闲时间
---- ---- 如果超时,获取连接失败,返回nullptr
---- ---- 如果在最大空闲时间内获取,检查到非空,则跳出循环
队列不为空
检查没有超过最大连接数量
创建连接,定义使用后资源的放回
通知生产者,我已经消费了一个连接,让生产者看看是否该生产了

最大空闲时间回收,扫描线程代码实践

在connection.h中添加有关时间的操作(应有三处)

	//刷新一下连接的起始空闲时间点
	void refreshAliveTime() {
    _alivetime = clock(); }
	//返回存活的时间
	clock_t getAliveTime() {
    return clock() - _alivetime; }
private:
	MYSQL* _conn;
	clock_t _alivetime;//记录进入空闲状态后的起始存活时间

在mys

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值