muduo -- Timing wheel 踢掉空闲连接

通过boost::circular_buffer + boost::unordered_set来模拟轮盘。

    typedef boost::unordered_set<EntryPtr> Bucket;
    typedef boost::circular_buffer<Bucket> WeakConnectionList;
    WeakConnectionList connectionBuckets_;

特性:
1.支持随机访问 
2.固定容量 
3.插入元素超过容量时会对头部或者尾部元素弹出
circular_buffer会自动弹出元素的特性:

1.buffer的元素保存Bucket,这个Bucket是一个集合,保存在1秒内所有连接的shared_ptr
2.对buffer进行特定大小的初始化,并用空填满 
3.当有一个连接的时候,将会把这个连接插入到Bucket里面
4.每一秒都会往buffer里面插入空的Bucket
5.这样基于circular_buffer的特性,现有的连接就会自动往前滚动
2.智能指针的使用

这里作者封装了一层结构Entry来管理TcpConnection,当circular_buffer将尾部 popback的时候,会依次调用其析构函数,并在析构函数主动断开连接。

当时有两个疑问: 
1.一个是在看源码时,每个TcpConnection有一个上下文Context变量保存Entry的WeakPtr。 
所谓上下文,就是变量,因为回调机制,每个连接都需要有其关联的Entry,这里直接用WeakPtr来作为上下文变量,不影响其引用计数。有了上下文,服务器每当收到客户端的消息时(onMessage),可以拿到与该连接关联的Entry的弱引用,再把它提升到强引用,插入到circular_buffer,这样就相当于把更新了该连接在时间轮盘里面的位置了,相应的use_count会加1。

2.一个是运行example时(build/release/bin/idleconnection_echo)每当有新的连接(onConnection),或者有新的消息(onMessage)时,智能指针对象的use_count都会先加2,然后再恢复正常的加1。

EntryPtr entry(new Entry(conn));
/*conn插入时间轮盘*/
connectionBuckets_.back().insert(entry);
dumpConnectionBuckets();

通过此处增加计数
在onConnection回调中,这里先创建了一个栈上shared_ptr,之后插入到unordered_set中,这里就会有引用计数就增加了两次,之后栈上变量销毁,引用计数回归正常。

#include <iostream>
#include <memory>
#include <unordered_set>
using namespace std;
typedef shared_ptr<int> IntPtr;
typedef unordered_set<IntPtr> IntPtrSet;
int main()
{
    IntPtrSet myset;
    {
        IntPtr ptr(new int(42));
        cout<<ptr.use_count()<<endl;
        myset.insert(ptr);
        auto it = myset.begin();
        cout<<it->use_count()<<endl;
    }
    auto it = myset.begin();
    cout<<it->use_count()<<endl;
    return 0;
}
//打印结果
//1
//2
//1

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值