对 IOCP 中的 IO 操作实现 超时 控制

97 views
Skip to first unread message

stephen.nil

unread,
May 17, 2008, 5:23:26 AM5/17/08
to dev4s...@googlegroups.com

在很多的 IOCP 例子程序中,都没有提到如何来做超时控制。
虽然 IOCP 可以支持很多的连接,但是在实际的环境中,如果不对 IO 操作做超时控制,也是有很大风险的。

在参考了 libevent 的做法之后,模仿 libevent 1.4 的做法,用一个 min-heap 来记录 IOCP 的 IO 操作。
当发起一个 IO 操作的时候,用 ( 当前时间 + 设定的超时时间 ) 作为这个操作的超时时间,
用这个超时时间作为 key ,在 min-heap 中插入一个记录。

按 min-heap 的定义,其中的第一个元素是最快超时的操作。
在 GQCS 的时候,通过拿当前时间和 min-heap 的第一个元素做比较,把两者的差值作为 GQCS 的超时时间。
当 GQCS 返回的时候,如果发现是超时事件,那么就从 min-heap 中把小于当前时间的所有操作都 pop 出来,这些操作都是已经超时的。

具体的实现代码,大概如下。
插入到 min-heap 的记录,通常就使用 PER_IO_DATA ,可能是这样的

struct PER_IO_DATA
{
OVERLAPPED overlapped;
...
...
int heapIndex;
struct timeval timeout;
};

就是在常见的 PER_IO_DATA 上加上 heapIndex 和 timeout 两个成员,提供给 min-heap 使用。

详细的实现代码,暂时可以通过 svn 得到。等代码经过更多的测试之后,将会发布一个新版本的 SPServer。

svn checkout http://spserver.googlecode.com/svn/trunk/ spserver-read-only


--------------
stephen.nil
2008-05-17

小贵子

unread,
May 17, 2008, 7:25:39 AM5/17/08
to dev4s...@googlegroups.com
嗯,对服务繁重且长时间运行的服务器,这会有一定的好处
可以进行下统计,看多少时间会出现这超时的情况
不过,服务繁重的服务器,如果IO处理不过来,超时的机率会大大增加

2008/5/17 stephen.nil <steph...@gmail.com>:



--
一把锋利的宝剑,要经过无数次的磨炼,才从愚钝走向飘逸

stephen.nil

unread,
May 17, 2008, 9:53:05 AM5/17/08
to dev4s...@googlegroups.com

对这个实现做了一个 2000 并发连接的测试,发现 server 占 CPU 很高。
不知道在 windows 下有没有工具能够查 程序 的瓶颈? linux 下倒有一个 cprof 库。

另外,有实现过类似功能的同学,能不能出来分享一下做法?

Best regards,

stephen.nil
2008-05-17

小贵子

unread,
May 18, 2008, 8:59:48 AM5/18/08
to dev4s...@googlegroups.com
可以的.用procexp.exe可以查看进程每一个线程的cpu占用率

2008/5/17 stephen.nil <steph...@gmail.com>:



--
一把锋利的宝剑,要经过无数次的磨炼,才从愚钝走向飘逸

小贵子

unread,
May 18, 2008, 9:02:51 AM5/18/08
to dev4s...@googlegroups.com
可以尝试把超时功能屏蔽掉,再测试看,是不是这个功能引用的

2008/5/18 小贵子 <xgz...@gmail.com>:



--
一把锋利的宝剑,要经过无数次的磨炼,才从愚钝走向飘逸

jlbnet

unread,
May 18, 2008, 9:38:05 PM5/18/08
to 高性能网络编程邮件列表
在windows 2k以上,控制面板/管理工具里有个 性能 的程序,在里面可以添加计数器,可以同时跟踪大量的事件,如cpu使用率,tcp数据发
送量,线程切换数等信息,很好用的

stephen.nil

unread,
May 19, 2008, 8:06:48 AM5/19/08
to 高性能网络编程邮件列表
Hi, jlbnet

试了一下,没发现怎么可以单独观察一个指定的程序?


Best regards,

stephen.nil
2008-05-19

stephen.nil

unread,
May 19, 2008, 8:06:48 AM5/19/08
to 高性能网络编程邮件列表
Hi, jlbnet

试了一下,没发现怎么可以单独观察一个指定的程序?


Best regards,

stephen.nil
2008-05-19

>>>

stephen.nil

unread,
May 19, 2008, 8:27:22 AM5/19/08
to dev4s...@googlegroups.com
Hi,
 
linux 下 cprof 可以做到类似这样的结果
 
   1. Function Name                        calls   func%  func(ms)    f+c%   f+c(ms)  
   2.                                          0 13660645568.442 11095652346241 100.000     81223  
   3. hashCode__19SP_CacheItemHandlerPCv   2600000   8.435      6851  13.449     10923  
   4. compare__19SP_CacheItemHandlerPCvT1    785604   2.392      1942   3.983      3235  
 
在程序执行结束之后,计算每个函数被调用了多少次,占用总执行时间的百分之几。
cprof 需要链接一个库到可执行程序中,也就是用 cprof 的时候,需要编译一个特别的版本来观察。
 
proxexp.exe 看起来是类似于 windows 任务管理 器,只能从外部观察,没有办法深入到函数这个级别。
而通常对于程序员进行优化的时候,比较有价值的信息是函数这个级别的。
 
 
Best regards,
 
stephen.nil
2008-05-19

小贵子

unread,
May 20, 2008, 12:33:36 AM5/20/08
to dev4s...@googlegroups.com
那windows下没有这方面的免费库
不过,有一些专门测试程序各方面性能的软件,比如AQTime
只要你编译一个debug版本的产品,然后从AQTime来启动你的产品(启动时,选择为性能检测),运行一短时间后,停止,就可以看到每一个函数的运行和调用情况了

2008/5/19 stephen.nil <steph...@gmail.com>:



--
一把锋利的宝剑,要经过无数次的磨炼,才从愚钝走向飘逸

永恒白天

unread,
May 20, 2008, 5:12:08 AM5/20/08
to 高性能网络编程邮件列表
windows下,vc2005提供了性能分析工具
intel也有性能分析工具for vc2003/2005的
当然,vc2005不是免费的,intel的性能分析工具也不是免费的
不过两款性能分析工具都非常管用,如果提供pdb的话,可以将每个函数调用次数,使用时间,用户态时间,内核态时间显示出来,
更能按照总时间占用比进行排序,这样就能找到那些本不应该大量占用时间的函数或瓶颈所在

jlbnet

unread,
May 20, 2008, 11:50:40 PM5/20/08
to 高性能网络编程邮件列表
windows确实没有自带的工具可以查看到函数级。
这个性能的工具可以监控到指定的程序的,在右边空白的地方点右键,选 添加计数器
然后在 性能对象 中,选择 Process, 在右下边的 “从列表中选择范例”,就可以看到当前所有运行的进程了。
左下角是要对进程要监控的内容,右下角是要监控的进程。
Reply all
Reply to author
Forward
0 new messages