muduo -- Timing wheel 踢掉空闲连接

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

    typedef boost::unordered_set Bucket;
    typedef boost::circular_buffer 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 
#include 
#include 
using namespace std;
typedef shared_ptr IntPtr;
typedef unordered_set IntPtrSet;
int main()
{
    IntPtrSet myset;
    {
        IntPtr ptr(new int(42));
        cout<use_count()<use_count()<

 

 

 

你可能感兴趣的:(muduo)