• SOCKET各种模型下并发数量


    转载自:http://fpcfjf.blog.163.com/blog/static/5546979320108230035670/

    今天在公司认真的看了一下SOCKET的编程,对其中一些编程模型的并发数量原来一直是半清不明,正好趁着做当前项目的机会把他理清,目前在SOCKET上的编程模型主要有以下几种(WIN为主,LINUX和UNIX用得较少):
    1、普通的阻塞和非阻塞编程。
    利用线程池技术和内存池,SOCKET池技术,基本可以处理一千五百个左右的SOCKET连接,但我们一般使用的机器大约有两M内存,而在不改变线程堆栈的大小情况下,我们至多可以创建一千七八百个线程,不过也就基本动不了了。我们测试基本到一千个线程左右,机器就很慢了。
    还有在WIN-XP-SP2中,对单进程中的线程的并发做了处理,默认是10个,修改的方法网上多的是。
    2、SELECT模型(异步和同步)
    这个模型在单线程的情况下默认是64个最大SOCKET连接。你可以修改WINSOCK2.h这个文件中的FD_SETSIZE,但不得超过底层WINSOCK的限制(1024),但如果采用多线程的话,可以处理更多,其实际的最大数量,在单线程里建议不超过1000个,至于多线程,应该也要控制线程切换的效率和数据处理的时间。应该几千个没有什么问题。
    3、WSAASYNCSELECT模型
    这个模型利用的是消息机制,建议不超过1000个。
    4、WSAEVENTSELECT模型
    这个模型利用的是事件驱动方式,单个线程不超过64个(WSAWaitForMultipleEvents最多等待64个事件),如果多SOCKET并发宜采用线程池技术,应该几千个没什么问题。
    5、重叠IO
    应该几千个没问题。这个毕竟是下面IOCP的一个技术基础。
    6、IOCP完成端口+重叠IO
    这个是解决SOCKET通信的终极武器,可惜只用在WIN上和2000以上,LINUX上好象有一个类似的EPOLL,而且好象比这个还好用,没具体用过。这个东东解决几万个SOCKET并发应该是很轻松,当然你得编程水平和技术得跟上。
    从网上查看说这个东西如果使用的服务器版的操作系统和机器最大可到一百W,太恐怖了吧,那家伙自己在XP上最大达到了五万,但不断出现内存溢出的BUG。他最高到了9W。


    顺道把NET下的SOCKET通信并发搞一下,是从别人的BLOG上摘来的:
    .NET平台下几种SOCKET模型的简要性能供参考
    这个内容在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能实现多少最大连接,没有资料可以查,如果有朋友知道,可以讨论一下。另外上面提到的许多数据,是从一些资料上摘抄下来的,我没有自己试过,仅仅是拿出来和大家讨论一下。我想,一个高性能的服务端程序,可能需要的技术不仅仅是采用什么模型,还有许多细节需要注意,比如内存的处理,采用什么算法等等,当然,这仅仅是软件成本上的,硬件上肯定也是需要投入的。

  • 相关阅读:
    Java对MongoDB的CRUD
    MongoDB数据库基本用法
    MySQL order by 排序结果不正确
    Linux shell 脚本 eq,ne,le,ge,lt,gt意义
    Linux shell 命令运行符 &,;,&& 区别
    Linux netstat 命令详解
    Linux ss 命令详解
    Linux sort 命令详解
    Linux sed 命令详解
    Linux xargs 命令详解
  • 原文地址:https://www.cnblogs.com/jeekun/p/1963498.html
Copyright © 2020-2023  润新知