当前位置:首页 > 物联网 > 《物联网技术》杂志
[导读]摘 要:介绍了Windows最复杂的内核对象IOCP (I/O Completion Port输入/输出完成端口)的基本原理。利用完成端 口机制,应用程序能够为数百上千的用户服务。文章通过完成端口对象指定一定数量的线程,对重叠I/O请求进行管理,从而 为已完成的重叠I/O请求提供服务。通过该模型编写的网络服务应用程序可以达到较好的性能。

引言

与计算机执行的大多数其他操作相比,设备I/O是其中 最慢、最不可预测的操作之一。比如CPU从硬盘文件中读写、 网络读取数据等,每一线程要等待I/O操作完成再执行后续 的代码。让太多或者太少的服务器线程来处理线程,都可能 会导致性能问题。使用异步设备I/O可以将请求交给设备的 驱动程序去处理,应用程序的线程可以执行其他有用的任务。 这样可以更好地使用资源并创建出更高效的应用程序。

但是,随着客户端请求、退出的增加,会有许多的并发 线程并发执行。由于这些线程都是可运行状态,Windows内 核会浪费太多时间来进行活动线程的上下文切换,如不断新 建和销毁线程。Windows提供了 I/O完成端口机制可以很好 地解决上述问题。

IOCP模型

当我们创建一个I/O完成端口的时候,系统内核实际上 会创建5个不同数据结构。完成端口会将客户请求加入到一 个公共的消息队列中,然后应用程序会创建一个线程池来处 理客户的请求。当设备与I/O完成端口相关联后,系统会检查 是否有与设备相关的一个I/O端口,若有则会将已完成的I/O 请求追加到消息队列,并调用相关的工作线程来处理这个请求。 当这个请求被处理完后,系统会通过一种机制通知客户,客户 只需要取处理好的数据即可。图1所示是一个完成端口模型 的结构示意图。

IOCP模型的使用

在实现异步通信机制的时候,一般要用到一个核心数据 结构重叠(OVERLAPPED)结构。OVERLAPPED结构定义

如下:

typedef struct _OVERLAPPED

{

DWORD Internal ;//[out]保存已处理的I/O请求的错误码 DWORD InternalHigh ; //[out]异步I/O完成保存已传输的字 节数

DWORD Offset ; //[int]文件传送的字节偏移量的低位字 DWORD OffsetHigh ;//[int]文件传送的字节偏移量的高位字 HANDLE hEvent ; //[in]指定一个I/O操作完成后触发的事件 [OVERLAPPED, *LPOVERLAPPED ;

OVERLAPPED结构执行两个重要的功能:第一,它像 一把钥匙,用以识别每一个目前正在进行的overlapped操 作,比如在网络发送和接收数据时,都会用到WSASend()和 WSARecv。函数,参数里面都会附带一个重叠结构,这个重 叠结构我们可以理解为一个网络操作的ID号,通过这个ID 号就可以区分是对哪个网络进行操作了;第二,它在你和系统 之间提供了一个共享区域,参数可以在该区域中双向传递。

基于完成端口模型的应用程序实现

2.1创建I/O完成端口

_inHANDLEFileHandle,

_in_optHANDLEExistingCompletionPort,

_inULONG_PTRCompletionKey,

_inDWORDNumberOfConcurrentThreads);

PULONG_PTRlpCompletionKey,//当文件I/O操作完成后,用于存放与之关联的CK(套接字信息结构体指针)

LPOVERLAPPED*lpOverlapped,//为调用IOCP机制所引用的OVERLAPPED结构

DWORDdwMilliseconds,//用于指定调用者等待

该函数用于创建一个完成端口对象和将一个句柄同完成CP的时间

端口关联在一起。在创建一个完成端口时,前三个参数都会忽);

略,NumberOfConcurrentThreads参数指定允许有多少线程处于可运行状态。通常给NumberOfConcurrentThreads参数当一^工作者线程从GetQueuedCompletionStatus调用中接收到I/O完成通知后,在lpCompletion和lpOverlapped参

设为0,那么I/O完成端口会使用默认值,也就是允许并发执数中,会包含一些必要的套接字信息。利用这些信息,可通

行的线程数量等于主机的CPU数量,避免额外的上下文切换。

过完成端口,继续在一个套接字上进行I/O处理。通过这些

代码如下:hIOCP=CreateIoCompletionPort(INVALID_HANDLE

VALUE,NULL,0,0);

2.2工作者线程和完成端口

成功创建一个完成端口后,便可开始将套接字句柄和对象关联到一起。但是在关联套接字之前,必须创建一个或多个工作者线程,以便在I/O请求投递完成端口对象后,为完成端口提供服务。应该创建多少个线程?在此要记住一个重点,在调用CreateIoCompletionPort时指定的并发线程数量,与打算创建的线程池线程数量是有区别的。假如在完成端口上创建的工作者线程数量超过指定并发执行的线性数量(这里设为n个),那么系统最多只允许n个线程运行。因为我们随时都能执行更多的线程,比如调用了函数Sleep或WaitForSingleObject使其处于暂停状态,就要用另外线程代替。为了充分发挥系统性能,一般设置为CPU的数量乘以2。

2.3完成端口与重叠I/O

创建好工作者线程后,调用GetQueuedCompletionStatus)函数让句柄和完成端口相关联起来,进行I/O请求处理。它将调用线程切换到睡眠状态,直到指定的完成端口的队列中出现该请求。如以套接字句柄为基础,投递数据发送和接收请求,会扫描完成端口的队列里是否有网络通信的请求存在(如读取数据、发送数据等),一旦发现消息队列中出现一项的时候,该完成端口会唤醒线性池中的一个线程。这个线程会得到已完成I/O项中的所有信息:

已传输的字节数、完成键以及OVERLAPPED结构的地址。GetQueuedCompletionStatus()函数定义如下:

BOOLGetQueuedCompletionStatus(

HANDLECompletionPort,//指定的IOCP,该值由CreateIoCompletionPort函数创建

LPDWORDlpNumberOfBytes,//一次完成后的I/O操作所传送数据的字节数

参数,可获得两种重要的套接字数据类型:单句柄数据以及单I/O操作数据。单I/O操作数据是CompletionKey(完成键)参数标识的是某个特定的套接字句柄数据,相当于用一个标志来绑定每一个I/O操作,这样收到网络操作完成的通知后,可以通过这个标志来找出返回的数据对应的I/O操作。该标志可以定义如下:

typedefstruct_PER_IO_CONTEXT{

OVERLAPPEDm_Overlapped;//每一^重叠I/O网络操作都要有一个

SOCKETm_sockAccept;//这个I/O操作所使用的Socket,每个连接的都是一样的

WSABUFm_wsaBuf;//存储数据的缓冲区,用来给重叠操作传递参数的

charm_szBuffer[MAX_BUFFER_LEN];//对应WSABUF里的缓冲区

OPERATION_TYPEm_OpType;//标志这个重叠1/O操作是做什么的,例如Accept/Recv等}PER_IO_CONTEXT,*PPER_IO_CONTEXT;

该结构关联了与I/O操作的某些重要数据元素,例如完成I/O操作发送或接受请求的类型m_OpType。每一个I/O操作对应了响应的PER_IO_CONTEXT,我们还要定义单句柄数据来管理句柄上的所有I/O请求,如在Socket上投递了多个AcceptEx请求,该结构定义如下:

typedefstruct_PER_SOCKET_CONTEXT{

SOCKETm_Socket;//每一个客户端连接的Socket

SOCKADDR_INm_ClientAddr;//这个客户端的地址

CArray<_PER_IO_CONTEXT*>m_arrayIoContext;//数组,所有客户端IO操作的参数,也就是说对于每一个客户端Socket是可以在上面同时投递多个IO请求的

2014年/第3期物联网技术61\}PER_SOCKET_CONTEXT,*PPER_SOCKET_CONTEXT;

2.4关闭IOCP

调用PostQueuedCompletionStatus函数,向每个工作者线程都发送一个特殊的完成数据包。可以唤醒那些还在等待完成端口但又没有已完成的I/O请求,每个线程会对GetQueuedCompletionStatus的返回值进行检查,如果发现应用程序正在终止,那么它就可以进行清理工作并正常的退出。

3IOCP程序流程

该程序调用高性能特性的AcceptEx函数用来完成端口异步,取消了阻塞方式的Accept调用。我们知道,AcceptEx是在客户端连入之前就把客户端的Socket建立好了,而不需要像Accept那样在客户端连入之后,再去时间去建立Socket。统可能来不及为更多的并发客户端现场准备Socket。另外,相比Accept只能阻塞方式建立一个连入接口而AcceptEx可以同时在完成端口上投递多个请求。图2所示是其程序的整体流程图。

基于完成端口模型的应用程序实现

4结语

采用I/O完成端口编写的服务应用程序,经过ProcessExplorer测试发现当服务器收到3000个并发线程的时候CPU占有率约为4%,而采用了多个并发线程的客户端程序CPU占有率约为12%。所以,如果预计到自己的服务器在任何给定的时间,都会为大量I/O请求提供服务,便应考虑使用I/O完成端口模型,从而获得更好的性能。但是在编写基于完成端口的系统创建一个Socket的开销是相当高了,用Accept的话,系服务应用程序时,还应注意重叠操作可确保按照应用程序安排好的顺序执行。然而,不能确保从完成端口返回的完成通知也按照上述顺序执行。在对数据包有要求的时候,比如传送大数据的时候,要注意这个顺序。

20211120_6197d4b147075__基于完成端口模型的应用程序实现

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

凭借其全新的功能丰富的移动交易应用程序,屡获殊荣的经纪商HFM让客户实现触手可及的全方位交易体验。 毛里求斯路易港2022年10月14日 /美通社/ -- 全球多资产经纪商...

关键字: 应用程序 FM 移动应用 ADI

伦敦2022年10月13日 /美通社/ -- Ubuntu Pro是扩展式安全维护和合规订阅服务,目前针对数据中心和工作站已推出公开测试Beta版本。Canonical将按照...

关键字: UBUNTU CANONICAL BSP 应用程序

加拿大政府9月26日表示,从2022年10月1日起,加拿大将取消所有疫情下的旅行限制,包括对乘坐航班和火车乘客的疫苗接种和口罩要求。所有旅行者(无论国籍)从10月1日开始将不必通过ArriveCAN应用程序提交健康信息或...

关键字: ECAN 应用程序 飞机 ARRI

SIXT管理委员会批准整体可持续发展计划,以进一步加快二氧化碳减排和智能新能源出行需求 到2030年, SIXT在欧洲车队中的新能源车将达到70%至90% 投资5000万欧元:公司将大...

关键字: 可持续发展 新能源汽车 应用程序 移动平台

(全球TMT2022年9月22日讯)建筑项目管理软件领域企业InEight Inc.宣布了最新的软件创新,包括范围、设计和资源管理方面的新流程标准化,以及新的进展跟踪功能和创建基准验证型进程预估和时间表的能力。该更新还...

关键字: 软件 进程 应用程序 模板

InEight专注于软件创新的标准化和基准更新,从而提高了效率,增加了项目信心 InEight建筑项目管理平台的最新发展引入了新的设计管理和基准实践,提高了各个项目之间的一...

关键字: 软件 应用程序 进程 移动应用

Sumo Logic可靠性管理为企业领导者提供关键数据,以平衡创新速度和服务可靠性

关键字: LOGIC 应用程序 PEN COM

中国晋城2022年9月7日 /美通社/ -- 希尔顿集团 (NYSE: HLT)今日宣布,晋城古书院希尔顿花园酒店正式开门迎客。作为集团旗下标志性高端精选服务酒店,首次进驻山西省的晋城古书院希尔顿花园酒店,将秉承品牌在全...

关键字: MIDDOT BSP 应用程序 感应器

(全球TMT2022年9月6日讯)近年来美网在提升数字体验方面下了功夫,这背后,作为赛事主办方美国网球协会 (USTA)长期合作伙伴的IBM及其众多数字化解决方案功不可没。很长时间以来,IBM Consulting与美...

关键字: IBM 数字化 应用程序 CODE

洛杉矶2022年8月31日 /美通社/ -- 由INKA Entworks提供的领先云端到端移动应用保护解决方案AppSealing宣布,公司荣获2022年Gartner Hype Cycle应用安全"榜样供应...

关键字: PSE APPS GARTNER 应用程序

《物联网技术》杂志

2511 篇文章

关注

发布文章

编辑精选

技术子站

关闭