RDP(可靠UDP协议)Socket API高性能扩展接口: 异步非阻塞I/O(RDPAIO API)

来源:互联网 发布:java权限管理源码 编辑:程序博客网 时间:2024/05/16 12:28

(此文由nunix@sohu.com原创,转载请注明出处)

 

一、RDPAIO简介:

       为提高多并发多连接环境下的数据吞吐量,RDP实现了异步非阻塞I/O模型,并在原RDP Socket API基础上扩展了一组RDPAIO接口函数,即RDPAIO API

二、I/O通讯模型简介:

       在介绍RDPAIO之前,先简单的解释一下几个I/O通讯模型中的常用概念

       1、阻塞:应用程序挂起(Suspend)直到当前I/O操作结束。

       2、非阻塞:应用程序立即返回,不管I/O操作是否成功。

       3、同步:应用程序流程与I/O操作流程保持一致。

       4、异步:可以连续发起多个I/O操作,应用程序不必与I/O操作流程保持一致。

 

       基于这4个概念,衍生出4种通讯模型:

       A、同步阻塞:利用挂起等待I/O操作完成的方式保持应用程序和I/O操作流程一致。

              优点:这是最简单的一种通讯模型,对于少量I/O操作来说也是最高效的一种方式。由于阻塞调用会挂起进程,在实际开发中会使用多线程技术实现对多个I/O操作的管理(一个I/O操作对应一个线程),这样读、写等I/O阻塞只会影响某个线程,不会使整个进程挂起。

              缺点:当进程在处理大量I/O操作时不得不创建大量的线程,CPU会大量耗时在线程内核切换上,直至进程瘫痪,因此这种模型不适合大量高并发I/O处理的应用场合。

              这种模型的实现如TCP accept/read/write 系列函数以及RDP提供的RDPAccept / RDPSend / RDPRecv接口。

       B、同步非阻塞:利用对当前I/O操作状态的轮询直至I/O操作完成来保持应用程序和I/O操作流程一致。

              优点:除了看起来不会阻塞进程,没有任何优点。如果轮询间隔时间太短,就近乎阻塞,但较阻塞更耗CPU。如果轮询间隔时间过长,则会导致数据吞吐量的降低。

              缺点:最低效、最难控制的模型。

              TCP accept/read/write 提供非阻塞设置,但一般都用异步方式来调用。 RDP同类函数不提供非阻塞调用。

       C、异步阻塞:这种模式可以连续发起多个非阻塞I/O操作,然后使用阻塞select调用来轮询I/O操作状态。

              优点:这是异步方式最简单的一种实现,同样应用程序开发也很简单。可以通过一个线程来管理多个I/O操作。

              缺点:一般的select实现是通过对集合结构的轮询来管理多个I/O操作符(Socket),当管理大量连接是难免性能低下,基本不适合应用在高性能I/O操作场合。

              TCPselect模型就是这种实现。RDP 不提供类似实现。

       D:异步非阻塞:这种模式可以连续发起多个非阻塞I/O操作,当操作完成时通过消息或线程回调函数通知应用程序。

              优点:这是在高性能I/O应用场合最广泛的一种模型,实际开发中只需一个或几个(根据CPU数量自定义)线程来对多个I/O操作控制。

              缺点:对于少量I/O操作来说性能不如同步阻塞,毕竟消息或回调线程通知都耗CPU时间。另外应用程序开发相对较复杂。

              标准TCP API提供的重叠I/O调用就是这种模型。Windows环境下的完成端口模型(IOCP) Linux下的异步I/O模型(AIO)是对重叠I/O对优化和扩展。 RDP针对自身协议的特点实现了RDPAIO接口。

 

       综上所述,同步阻塞模型(针对少量I/O操作)和异步非阻塞(针对大量I/O操作)有较高的实现价值,所以RDP Socket API只实现了这两中模型。而其他同类可靠UDP库实现异步I/O操作较多采用select模型。

三、RDPAIO特点:

       RDPAIO的设计参照了Windows的完成端口(ICOP)模型和Linux的异步I/O模型(AIO),先简单解释下这两种模型:

       1) Windows IOCP: 采用重叠I/O模型+消息队列来实现异步通讯。性能较高,但因是基于Socket API接口扩展而成,可能会造成初学者混淆,开发较困难。

       2) Linux AIO:采用重叠I/O模型+事件或回调线程函数通知来实现异步通讯。脱离原有Socket API,提供给用户新的简易的接口,使初学者上手容易。

       结合以上两者优点,RDPAIO采用了用重叠I/O模型+消息队列实现了异步通讯,并用仿Linux AIO API函数库形式封装了这种模型,使第三方更容易调用。

四、调用接口:

RDPAIO RDPCreateAIO(); //    创建一个AIO句柄.

int RDPAioLink( RDPSOCKET sock,RDPAIO aio ); //关联一个RDPSOCKETRDPAIO. 需要在RDPListenRDPConnect或接受到连接后调用。

int RDPAioPost( RDPAioContext *lpAioContext );//投递一个I/O请求

int RDPAioReturn( RDPAIO aio,RDPAioContext **lpAioContext,int time );//    RDPAIO队列获取已执行完成的操作.

void RDPAioClose( RDPAIO aio ); //关闭一个RDPAIO 

 

  在今后的文中,可能会提到RDP Socket API的某些开发细节,以及提供测试用例,感谢大家关注!

原创粉丝点击