这个内容在cnblogs中也讨论过很多次了,这两天大概看了一些资料,看到一些简单的性能指标拿出来和大家讨论一下。
socket + threads/threadpool
大概性能:小于1500个连接
实现:accept一个socket,就交给一个线程去管理,比较笨,但也比较有效,因为是同步方式,控制起来很方便。高级点的,就是交给一个线程池去管理,线程池由系统自动托管,省去了开销线程的时间。一般小型项目,用这个完全足够,开发也简单。但要注意,如果若干socket长时间占用线程池中的线程,同时其它连接数又比较多,很容易出现提示说你没有足够的线程供使用。呵呵,让socket少做点事,少占用时间,换一个快点的cpu是不错的方式。另外,如果有一些比较好的第三方线程池组件,也可以选择使用,比如smartthreadpool。
socket + select
大概性能:大于1500个连接后性能下降
实现:select是很常用的一种模型。是在阻塞功能中轮询一个或多个socket,将要处理的socket放到一个ilist中,当select轮询结束后,然后我们再自己处理这个ilist中的socket。具体的用法可以看一下msdn。select的效率并不能说是高的,因为当队列中待处理的socket比较多的时候,处理最后几个socket相当于要遍历所有前面的socket,非常不划算的。
socket + asynchronous
大概性能:约7500个客户端连接
实现:beginxxxx,endxxxx,再熟悉不过了吧。异步socket归根到底,还是用的线程池技术,用线程池来处理异步io。这就又引出个问题,.net的线程池又是用的什么实现方式,以前看过有人说,.net的线程池是用的完成端口来实现的,我不知道这样的说法是不是正确,从查到的资料中也没有办法确认(希望这点有朋友可以告诉我)。异步socket对于程序的处理流程来说比同步复杂了许多,异步回调函数的控制不如同步方式那样直观。但有一点我想应该是要注意的,就是回调函数应该轻装上阵,不应该处理过多的事务,对传递数据的处理,应该交给其它线程进行处理。
iocp(完成端口)
大概性能:约20000~50000个客户端连接
实现:现在.net下有一些伪iocp,大家可以去搜索一下,还没有见过开放出来的用这些伪iocp来实现的socket例子。我说的20000~50000个客户端连接,是指在c++下开发的情况,这样的情况下,需要用到的基本技术还包括内存池、查询算法等。
伪iocp能实现多少最大连接,没有资料可以查,如果有朋友知道,可以讨论一下。另外上面提到的许多数据,是从一些资料上摘抄下来的,我没有自己试过,仅仅是拿出来和大家讨论一下。我想,一个高性能的服务端程序,可能需要的技术不仅仅是采用什么模型,还有许多细节需要注意,比如内存的处理,采用什么算法等等,当然,这仅仅是软件成本上的,硬件上肯定也是需要投入的。
新闻热点
疑难解答
图片精选