java 完成端口_IO完成端口(IOCP)

1 概述

IO完成端口是windows下性能最好的IO模型。

windows下的socket也是一种IO,所以完成端口也是最好的socket IO模型。

不幸的是,IO完成端口非常复杂,理解它门槛已经非常很高,而正确使用的门槛比理解它还要高很多。

之所以这么难理解,很大原因也在于没有好的资料。MSDN的文档已经相当良心的完善,但是还是有许多的问题没有解释清楚,整个模型的机制模糊不清。而网上的文档只能作为入门,里面的内容离实际可用的代码有十万八千里那么远,比如很多的文档连发送的功能都没有讲到。至于udp使用iocp,就更少有资料了。

2 简化模型图

这个最简单的模型,用来表示IOCP涉及到的对象。

这里有三个对象,主线程,socket工作线程,系统API模块。

上面是用户代码层,下面是系统的IOCP API层。主线程和工作线程都处于用户代码层。

3 简化流程图

这个最简单的流程图,表示了主线程和Socket工作线程的主要流程。

简单的描叙一下:

(1)主线程通常是消息循环线程。主线程调用系统IOCP API发起操作(如WSARecv开始收Socket数据),请求系统完成该操作。

(2)系统收到操作请求,进行处理(如开始收Socket数据),并在处理完成时(如收到了60K数据),发出事件,事件会唤醒工作线程。

(3)工作线程通常是普通线程。阻塞等待事件,处理事件,并发送消息通知主线程(如"收到60K的Socket数据消息")。

(4)主线程收到消息,处理消息(如"收到60K的Socket数据消息"),处理业务逻辑(比如在界面上显示:你收到一条新的消息)。

4 模型要素

4.1 异步操作

异步操作是一个函数,该函数立即返回,作用是请求系统完成一些事情,系统经过一段时间完成了,就触发一个系统事件,唤醒等待事件的线程。

异步操作有:WSASend(发送数据),WSARecv(接受数据),PostQueuedCompletionStatus(发自定义事件)。

4.2 系统事件

系统事件有:Socket事件(发送SOCKET数据完成事件,收到数据事件,SOCKET断开连接事件),自定义事件:通过PostQueuedCompletionStatus发送的事件。

4.3 主线程

主线程通常是业务逻辑的所在,我们这里假设主线程是消息循环线程。

主线程建立和销毁工作线程,建立的过程很简单,这里略去,销毁的时候,是通过发送一个事件给工作线程,工作线程被唤醒并处理事件,退出。

主线程可以调用系统IOCP函数(如WSARecv函数接受Socket数据),该函数立即返回,不阻塞主线程。

主线程会收到工作线程发过来的消息(例如收到数据消息)。

4.4 工作线程

工作线程通常不做复杂的业务逻辑,是一个普通线程。

工作线程阻塞等待系统事件(GetQueuedCompletionStatus),每当收到系统事件,就会被唤醒,然后简单处理事件:例如把收到的Socket数据包装成一个消息,发送给主线程。

5 事件和操作

5.1 事件和操作之间基本关系

(1)只有发出操作,才可能收到事件。不发出操作,不会收到事件。

(2)发出一个操作,收到一个事件。

5.2 WSARecv操作

有可能收到“SOCKET收到数据事件”,“SOCKET断开连接事件”。

调用WSARecv函数

(1)如果系统之前已经接收了Socket数据:

函数返回值为0,函数的出参里已经有收到的Socket数据了,但是,阻塞等待的线程依然会收到事件,事件的参数里面也带有Socket数据。

(2)如果系统之前没有接收到Socket数据:

函数返回值不为0,如果WSAGetLastError为WSA_IO_PENDING时,表示投递该操作给系统成功,阻塞等待的线程会收到事件(该事件有可能表示真的收到了数据,也可能是收数据失败)。

5.3 WSASend操作

有可能收到“SOCKET发送数据完成事件”,“SOCKET断开连接事件”。

当收到“发送数据完成事件”,并不代表数据真的发送完成,可能实际上只发了一部分,对方只收到一部分。

6 实际模型

实际的服务器模型更加复杂,这个图还是简化了的,没有画上accept部分。

图中,网络模块和逻辑模块都属于用户层代码。

系统API模块有两个socket IO线程,一般来说,系统API层的线程数为:CPU数目*2。

网络模块有四个SOCKET工作线程。一般来说,用户层的SOCKET工作线程数为:CPU数目*4。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值