基于线程池的网络程序性能分析

danscort2000 2006-04-19 12:10:18

看到论坛里很多人一看见模型就是IOCP
我实在搞不明白,为什么要IOCP?有必要吗?一定要学吗?代价是多少?
MS虽然说了使用IOCP在WINDOWS下效率比较高,
但是只是个比较而已,相对于硬件的飞速发展,那点提高几乎可以忽略
况且使用IOCP,等于和LINUX/UNIX说GOODBYE,使用人家封装好的类,自己根本不懂原理是什么,
如何去为特定使用做优化,就好象现在还有人在问TCP粘包问题一样,最基本的东西还没搞清楚

使用WINSOCK API,完全可以自己实现类似的功能,为自己的应用而优化,通用不等于100%管用,不从底层实现做起,等你的软件做大了就会感到后怕

我比较喜欢用多线程来编写网络程序的,使用线程池技术,完全可以做到同样优秀的性能,而且代码简化,很多人可能一看到多线程,特别是上千个线程同时运行的时候,上下文切换动作就要占用很多时间了,实际上,相对于现在的硬件,特别是在WIN2003上,速度之快你无法想象,下面是我在 CELERON 700M(100*7) WIN2000 PRO环境下 模拟运算得到的结果
一共1500个线程[1M STACK 2*4KB DEFAULT]同时运行 ,每线程运行 1200次 ,每次 运算包括一个 内核加操作 2个用户态 除法和加法操作 ,全局变量操作 ,然后强制切换线程
得到的结果是: 每秒 WIN2000 PRO环境下可以切换 20万次 以上[包括了监控线程非常耗费CPU的界面输出操作], 其他操作依然响应正常

对于网络程序,采用阻塞的模式下,实际的每次切换操作到换出,CPU占用和我模拟的线程差距不大,
而现在的服务器处理器,基本都是几乎2G 1MCCHE以上,而且至少是DDR内存,在WIN2003下,速度更快,因为2003下为后台线程做了优化,特别是开启线程的速度,几乎是2000 PRO的10倍以上

所以,对于几千个连接,如果你不是绝对必要,完全没必要在乎使用什么模型
UNIX/LINUX下没有IOCP几十年,使用FORK用了几十年,造样在稳定运行并性能优秀,使用比进程要轻的多的线程,完全可以实现更加优秀的性能
...全文
4900 65 打赏 收藏 转发到动态 举报
写回复
用AI写文章
65 条回复
切换为时间正序
请发表友善的回复…
发表回复
jyl168 2007-03-07
  • 打赏
  • 举报
回复
mark
shgmail 2007-03-07
  • 打赏
  • 举报
回复
mark
yyzhao21 2007-01-25
  • 打赏
  • 举报
回复
mark
dylgsy 2007-01-16
  • 打赏
  • 举报
回复
好,mark
ProgrameMan 2007-01-04
  • 打赏
  • 举报
回复
关注一下,有时间再看
microyzy 2007-01-04
  • 打赏
  • 举报
回复
只做过小规模的线程池服务器,mark一下
szjay 2006-05-02
  • 打赏
  • 举报
回复
楼主,光说是没结果的,来些实际的代码吧,找个同样的环境跑一下就知道了嘛。
getit911 2006-04-27
  • 打赏
  • 举报
回复
比较同意danscort2000对堆栈问题的解释,其实实际试过就知道,线程不需要太大堆栈。
getit911 2006-04-27
  • 打赏
  • 举报
回复
现在做Server端架构,如果还按照32位结构思考问题有点落伍了,也不应该继续堆栈内存打转,而应该考虑如何实现良好的可维护、可扩展性,以及如何充分利用当前强大的硬件资源。
danscort2000 2006-04-27
  • 打赏
  • 举报
回复
没想到有这么多人进来

我写的服务器程序有两个版本

一个标准版本采用的是线程池模型
一个专业版本采用了IO层与指令处理层分离的多线程设计[类似IOCP,但不是IOCP,是独立写的网络引擎],这个版本在调试
下面的那个测试完成,我给各位对比一下就知道了
目前采用调试版本和线程池版本做对比,在线程池容量范围内,采用分离设计的专业版本对并发连接的处理低于线程池模型,但是超过大约3000个的时候,线程池的效率开始下降并低于专业版本,也许发行版本的专业版速度更快

此外楼上的关于堆贱的描述是不正确的,默认堆贱是1M,但是事实上根本不需要,128KB足够绝大多数线程使用了,它的作用只是在调用函数的时候的参数传递,线程内部变量而已,默认只分配两个页面也就是8KB,并不是你保留128KB就给你实际分配128KB,这是虚拟分配,不够的时候才重新分配
因为象CSTRING等实际内存分配是全局堆中分配,而不是线程堆贱中[只分配一个指针,代码共用],你总不会在函数中直接采用对象进行传递吧,肯定是指针或者引用。
10000个线程虚拟开销的内存是大约1G虚拟内存,剩下的属于全局堆,实际占用物理内存大约是87MB左右10000个线程,这和虚拟内存要搞清楚





vclooker 2006-04-24
  • 打赏
  • 举报
回复
再补充一点,搂主讨论的起点就错了。iocp 在被介绍时更侧重的是可伸缩性,如果说线程池是收缩大系统的一种方式,那么iocp 只是在线程池上的附加的一个性能提升的操作而以。
楼主的例子只能说无知者无畏了
vclooker 2006-04-24
  • 打赏
  • 举报
回复
凡是用到线程池(主动对象模型)和完成对象模型的系统都应该是大型企业系统,不要幼稚到用10000个或者1000个线程测试就认为ok了,万应该只是基数,多看点设计类的东西吧,这么争论太幼稚了。
mmens 2006-04-24
  • 打赏
  • 举报
回复
mark
_七爷_ 2006-04-24
  • 打赏
  • 举报
回复
不知道都说了些什么,有时间我给大家点评一下
largewang 2006-04-24
  • 打赏
  • 举报
回复
这么热闹,mark一下
huangbeyond 2006-04-23
  • 打赏
  • 举报
回复
IOCP,在我写的服务器程序里,无非也仅仅是SOCKET的IO部分而已。良好的封装,仍然可以使那些用了IOCP的Win代码,快速地移植到Linux/Unix下,就像写一个自己的CFile/CString一样的类那么简单。

我用IOCP的时候,也没有完全照搬书本。完全是按照自己的类库特点和实现过程,来选择性使用。现阶段,我的IO模型,在接收数据时是WSARecv,在发送数据时是send,呵呵。
huangbeyond 2006-04-23
  • 打赏
  • 举报
回复
4G的寻址空间,开10000个线程,每线程只能使用4000/10000 = 0.4M堆栈。

就光这个0.4M的堆栈限制,就足以让程序员痛苦不堪了。没有什么东西能保证客户在连接服务器之后,所占用服务器内存不超过0.4M的。

例如:服务器提供数据下载功能。服务器不可能每1次都从数据库读取然后发给客户,必然是:预先读一定量(比如:100条记录)入内存,然后累计发给客户,依此循环直到完成。如果查询出的数据量超过0.4M,怎么办?!不入内存,每一次都去访问数据库?!这种程序的效率会非常低的。

我个人觉得:实在没有必要为了10000个线程而带来其它问题和隐患。从理论上说,别说10000个线程,就是100,0000个都可以,但是每个线程只能使用0.004M堆栈。这样的程序还有现实意义吗?

可以不用IOCP,但是线程池还是有必要的。


另外,从用户的角度说。我相信,很多网络管理员对“运行时,会启动成千上万的线程”的程序是会感到不安的。毕竟,线程是内核对象,属于内核态的不可分页内存。这种类型的内存在系统内是有上限的,用一点少一点,你的程序用了,其它的程序还跑不跑?如果是我遇上10000个线程的程序在运行,我简直怀疑是蠕虫了,呵呵。甚至我在写服务器程序时,都不敢消耗掉太多系统的CPU/内存资源,除非专机专用。

不必质疑“内核态的不可分页内存的上限”,大家可以用循环执行“CreateEvent”不释放,来测试一下。看看是不是能无限创建Event成功,看看各自的机器能承受多少内核对象的消耗。

如今的网络服务器的瓶颈,往往不是CPU/内存,而是数据库/网络带宽。

好的服务器程序,除了IO模型选择合理,更要一系列围绕IO模型展开的,设计精良,结构清晰,易维护的类/代码,以适应业务变化和功能更新。这才是较重要的。



至于“跑10000个线程”,这个话题本身,有些接近于“一个针尖可以站几个天使”了。
getit911 2006-04-22
  • 打赏
  • 举报
回复
32位处理器存在4GB内存限制,但在64位系统上(现在遍地都是)这个限制就可以忽略了,Linux下线程数量也要受到一定限制,不过这个可以通过修改代码解决。

虽然每个线程都要堆栈的,实际上每线程堆栈并不需要太大,Windows默认是1M字节,其实完全可以小于1M字节,嵌入式系统通常都是几十k级别的,精确调整线程堆栈可以节省很多资源,IOCP这东西现在看没什么大用了。
longge520 2006-04-22
  • 打赏
  • 举报
回复
关注
striking 2006-04-22
  • 打赏
  • 举报
回复
这样可以支持多久。gettickcout可以支持49.7天。
加载更多回复(45)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧