Windows高效通信模型之IOCP

来源:互联网 发布:黑龙江网络作家协会 编辑:程序博客网 时间:2024/06/08 14:52

今晚复习计网去了...然后思考了一下怎么解决今天下午那份代码,客户端被子线程阻塞的问题。就像之前说的,那份代码是“One-thread-per-client“的模型,对每个是客户端的连接请求,都要临时创建一个socket来处理,这样就造成了系统开销比较大的问题,而且线程之间的互相阻塞也是影响效率的重要原因。


于是上网找了一下相关的信息,发现Windows下有一种号称性能最好的通信模型,叫做IOCP,中文名称叫做完成端口模型。一开始听到这个名字也是云里雾里,为啥端口会和高效处理高并发任务请求扯上关系,难道是端口还有什么不为人知的秘密吗?


后来看了这份教程 http://www.cnblogs.com/lancidie/archive/2011/12/19/2293773.html 里面讲得比较快详细了,这里总结一下。


先拿目前的模型来开刀,每个线程处理一个客户端的连接请求,首先是没有办法处理大量的连接请求,比如我现在有10万个连接请求,服务器端这边就要创建对应的socket,显然这个开销是无法接受的。再者,这样的操作会导致CPU不断地进行上下文切换,这就会导致CPU的负载非常之大,显然也是不现实的。我们姑且称这种方式是”阻塞通信+多线程“,缺点是开销太大,对CPU不友好,阻塞操作太多,会导致用户体验很差。


那么我们就需要一种异步处理网络操作的模型,它的核心作用是在异步处理网络操作,使得CPU在网络操作执行的时候可以去执行别的任务,直到网络操作完成,再去获取处理后的数据。这里就用到了IOCP模型。


具体的介绍再上面贴的教程连链接里面已经写得很详细了,说白了,IOCP的核心思想跟操作系统里面引入的中断有点类似(这个比喻可能不恰当,但是在整个学习过程中我对IOCP的效果一直有一种既视感)。在执行I/O操作时,CPU不需要忙等待,一直轮询设备是否需要执行I/O操作,而是采用中断的机制,只有当产生I/O操作的时候才通知CPU去处理,其他时间CPU可以执行别的业务。


而IOCP的核心就在于维护一个公共的消息队列。首先创建2*CPU核心数的线程,作为Worker,初始的时候它们是空闲,被挂起的。然后再开辟一个单独的线程,来监听连接请求,每当有连接请求,就accept,并将网络操作放入消息队列中。此时,Worker线程排队从队列中取出这些操作请求并处理。注意,整个过程中主线程是非常空闲的,完全有能力去执行其他的任务。也就是说,现在我们有一条主线程,若干条Worker线程,还有一条监听线程。主线程把网络请求扔给Worker线程去做,自己就可以同步做别的事情,而不用被阻塞挂起,等待外部I/O完成了。而这个公共消息队列,就叫做”完成端口“,因为它是”完成“网络操作(属于外部I/O)之后再通知主线程把数据拿走...大概就是这么个模型。


实际上Windows的socket库已经提供了完整的完成端口API,我感觉只要学会调用各种API来搭建整个模型就够了,至于深入的实现,可能以后工作有需要的话再去探究。

看来要找个时间来改进一下整个通信模型了...然而接下来一段时间有得忙了,嘛,不过所谓的成长就是这样吧(真的无比渴望有个大佬带我)...


最后附上通过阻塞式的accept操作来实现IOCP模型的流程图吧,感觉已经写得非常清晰了:

0 0
原创粉丝点击