消费者线程的实现
大约 2 分钟
消费者线程的实现
//消费者线程函数,从队列中获取连接
shared_ptr<Connection> ConnectionPool::getConnection() {
unique_lock<mutex> lock(_queueMutex);
while(_connectionQue.empty()) {
cond.wait_for(lock, std::chrono::milliseconds(_connectionTimeout));
if(_connectionQue.empty()) {
LOG("获取空闲连接超时了...获取连接失败!");
return nullptr;
}
}
shared_ptr<Connection> sp(_connectionQue.front());
_connectionQue.pop();
if(_connectionQue.empty()) {
cond.notify_all();
}
}
再也不被时间束缚:C++ stdchrono时间库全面解析 - 知乎 (zhihu.com)
重置智能指针析构
shared_ptr<Connection> sp(_connectionQue.front(),
[&](Connection *pconn) {
// 这里是在服务器应用线程中调用的,所以一定要考虑队列的线程安全操作
unique_lock<mutex> lock(_queueMutex);
_connectionQue.push(pconn);
});
智能指针第二个参数传入函数对象可以重置析构函数,这里使用lambda表达式,但是要注意线程安全问题
wait_for()
优化
wait_for()
返回值是一个类,包含了 timeout
和no_timeout
wait_for()
可能会出现这种情况:生产者发出信号,该线程no_timeout
退出wait_for()
,但是手慢没有抢到队列中的连接_connectionQue.empty()
while (_connectionQue.empty())
{
if (std::cv_status::timeout == cond.wait_for(lock, std::chrono::milliseconds(_connectionTimeout)))
{
if (_connectionQue.empty())
{
LOG("获取空闲连接超时了...获取连接失败!");
return nullptr;
}
}
}
最终版 消费者线程处理函数
// 消费者线程函数,从队列中获取连接
shared_ptr<Connection> ConnectionPool::getConnection()
{
unique_lock<mutex> lock(_queueMutex);
while (_connectionQue.empty())
{
if (std::cv_status::timeout == cond.wait_for(lock, std::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 *pconn)
{
// 这里是在服务器应用线程中调用的,所以一定要考虑队列的线程安全操作
unique_lock<mutex> lock(_queueMutex);
_connectionQue.push(pconn);
});
_connectionQue.pop();
if (_connectionQue.empty())
{
cond.notify_all();
}
}