使用双向链表和Hashtable来加速处理“心跳”超时检测
2006-12-30 09:29
543 查看
“心跳”超时检测是几乎所有C/S结构的应用需要处理的一个问题。服务器需要通过它来及时清理意外中断的客户端。本文希望通过一种空间换时间的策略,使得检测时间从O(所有已连接客户端数)降低到O(已经超时的客户端数)。
一般来说,这个操作需要遍历所有的正在连接状态的客户端来找出哪些是已经超时的,算法复杂度为O(N)。在多线程服务器中,进行检测时需要对记录所有客户端的列表进行锁定,如果算法执行时间较长,则会使得系统中其他需要访问客户端列表的线程阻塞。
下文描述了空间换时间的具体措施:
数据结构
我们使用一个双向链表来存储已连接的客户端列表。该列表的添加操作和收到心跳数据包处理操作使得该链表保持按照最后一次收到心跳数据包绝对时间的升序排列。使用另外一个Hashtable来存储客户端对象与双向链表节点的映射关系。
添加新连接
新的客户端加入到队列末尾(复杂度O(1)),并且将客户端对象和其对应的双链表节点对象放入Hashtable中(复杂度也是O(1))。
收到心跳数据包处理
一旦底层传输接收到某个客户端发送到的“心跳”数据包,则首先根据它从Hashtable中取出双向链表节点对象(复杂度O(1)),将此节点移动到链表末尾(复杂度也是O(1))。
删除连接
如果某客户端连接正常退出或者超时退出,则首先根据它从Hashtable中取出双向链表节点对象(复杂度O(1)),然后Hashtable中将其删除,然后从双向链表中删除节点(复杂度也是O(1))。
“心跳”超时检测
从双向链表的头节点开始向后逐个检测客户端的“心跳”状态,遇到第一个正常的客户端之后即可停止检测。
一般来说,这个操作需要遍历所有的正在连接状态的客户端来找出哪些是已经超时的,算法复杂度为O(N)。在多线程服务器中,进行检测时需要对记录所有客户端的列表进行锁定,如果算法执行时间较长,则会使得系统中其他需要访问客户端列表的线程阻塞。
下文描述了空间换时间的具体措施:
数据结构
我们使用一个双向链表来存储已连接的客户端列表。该列表的添加操作和收到心跳数据包处理操作使得该链表保持按照最后一次收到心跳数据包绝对时间的升序排列。使用另外一个Hashtable来存储客户端对象与双向链表节点的映射关系。
添加新连接
新的客户端加入到队列末尾(复杂度O(1)),并且将客户端对象和其对应的双链表节点对象放入Hashtable中(复杂度也是O(1))。
收到心跳数据包处理
一旦底层传输接收到某个客户端发送到的“心跳”数据包,则首先根据它从Hashtable中取出双向链表节点对象(复杂度O(1)),将此节点移动到链表末尾(复杂度也是O(1))。
删除连接
如果某客户端连接正常退出或者超时退出,则首先根据它从Hashtable中取出双向链表节点对象(复杂度O(1)),然后Hashtable中将其删除,然后从双向链表中删除节点(复杂度也是O(1))。
“心跳”超时检测
从双向链表的头节点开始向后逐个检测客户端的“心跳”状态,遇到第一个正常的客户端之后即可停止检测。
相关文章推荐
- C语言:使用链表实现的可变长度字符串处理函数
- 内核链表实现分析与使用(双向环形链表)
- 双向链表的数据结构使用
- PHP 使用 Imagick 裁切/生成缩略图/添加水印, 自动检测和处理 GIF
- 双向链表的使用
- csu 1365 双向链表模拟超时
- VxWorks下使用双向链表的小例子
- 如何使用c语言实现双向链表的插入删除操作
- 1109. Group Photo (25) -- C++ list(双向链表使用)
- 使用C++实现的双向链表
- GLIB容器 链表 双向链表 HASH表 TREE 的使用
- 哈希表+双向链表的组合使用
- 【语言处理与Python】3.4使用正则表达式检测词组搭配
- 论文阅读笔记——使用双向PCA进行行人检测
- C# 使用Hashtable处理Ini文件
- 双向链表 只使用一个指针
- 使用ConcurrentDictionary替代Hashtable对多线程的对象缓存处理
- HashTable(不使用链表的散列表)
- 使用递归来实现双向链表里删除第一节点不是数字‘2’
- C++ 标准模板库STL 双向链表 list 使用方法与应用介绍(一)