IOCP完成端口详解1
完成端口讲解

完成端口一、什么是完成端口从本质上讲,完成端口是一种异步I/O技术,它提供一个内核对象,可以关联多个I/O设备,同时关联一个线程池,线程池中的线程通常处于睡眠状态,当有I/O出现时,完成端口唤醒等待线程队列中的线程进行处理。
完成端口有着良好的伸缩性灵活性以及较高的效率,一般用来创建大型的服务器。
我们知道,一个服务器应用程序结构可以分为串行模式和并发模式。
在串行模式中,一次只能处理一个请求,第二个请求必须等待第一个请求被处理完毕才能开始处理,适合于客户量比较小的情况;在并发模式中,针对每个请求创建一个线程,使得多个请求可以同时得到处理,因而提高了程序的性能。
但是,我们再进一步思考,如果有多个设备同时发出IO请求,那么在并发模式中也必须创建与之相同个数的线程,但是,CPU的个数是有限的,多于CPU个数的可运行线程就没有意义了,系统不得不在多个线程间进行上下文切换,以使得多个线程并发执行,这必然浪费宝贵的CPU周期。
另外,虽然创建线程较进程而言开销要小,但也并不意味着没有开销,尤其当数量比较大的时候。
在完成端口模型中,引入了线程池的概念,在应用程序初始化时创建一个线程池,在没有请求时处于等待状态,当请求完成时唤醒一个线程运行,运行完毕后重新放入线程池中,等待其他请求使用。
由于不必为每个请求创建一个线程,从而减少了线程的数量,省去了运行中途创建线程的开销,进一步提高了程序的性能。
二、完成端口的内部结构由于完成端口也是一个内核对象,故我们看一下它的内部结构。
完成端口对象包含五个不同的数据结构:1、设备列表:表相:设备句柄、完成键。
当调用CreateIoCompletionPort时将设备与完成端口关联起来,同时在该数据结构中创建一项。
每当向完成端口关联一个设备时,系统向该完成端口的设备列表中加入一条信息。
2、/index.php/Main_Page-->: 150%; mso-bidi-font-size: 10.5pt">I/O完成队列:表相:传输的字节数、32位完成键、I/O请求的OVERLAPPED结构指针、错误代码当一个设备的异步I/O请求完成时,系统检测该设备是否关联了一个完成端口,如果是,系统就向该完成端口的I/O完成队列中加入完成的I/O请求项。
完成端口详细解析

关于完成端口(IOCP)的文章汇总- [C/C++]版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明/logs/32007489.html首先讨论一下I/O Completion Ports试图解决什么样的问题。
写一个IO Intensive服务器程序,对每一个客户请求生成一个新的child process/worker thread来处理,每个process/thread使用同步IO,这是最经典古老的解法了。
在这之上的改进是prefork 多个process 或者使用线程池。
(使用process或thread,原理都差不多,thread的context switch花销要比process switch要小。
为了论述简单,下面只讨论线程。
)这种结构的并发性并不高,哪怕你用C++, C甚至汇编来写,效率都不会很高,究其原因,在于两点:一.同步IO,每个线程大多数时间在等IO request的结束。
IO相对于CPU,那是极极慢的。
我翻了翻手里的Computer Architecture, A Quantitative Approach第二版,1996年出的,里面对CPU Register, CPU Cache, RAM, Disk,列的access time如下:Java代码1.Registers: 2-5 nano seconds2.CPU Cache: 3-10 nano seconds3.RAM: 80-400 nano seconds4.Disk: 5000000 nano seconds (5 milli seconds)如今CPU又按照摩尔定律发展了十年后,这个硬盘还是机械式的磁头移来移去读写,尽管如今disk controller都有cache,也在发展,但和CPU相比,差距越来越大。
(谁有最新数据可以贴上来。
)二.生成数量大大超过CPU总数的线程。
这样做有两个弊端,第一是每个线程要占用内存,Windows底下每个thread自己stack的省缺大小为1M,32位程序下一个用户程序最大能利用的内存也就3G,生成3000个线程,内存就没了。
IOCP完成端口与长连接通讯

最近在写一个通讯代理程序的时候使用了IOCP通讯模型,几年前也使用过IOCP,不过当时的程序是基于短连接的,而这次是长连接的,写这个程序的过程中我觉得主要有以下几点值得注意:
1、整个程序的架构:程序由一个Accept线程,n个工作者线程,1个线程池管理线程,n个业务处理线程构成。Accept线程接收客户端连接并投递 WSARecv重叠操作,工作者线程中通过GetQueuedCompletionStatus阻塞收取数据,收取请求数据后将数据放入队列,然后再投递一个WSARecv重叠操作至GetQueuedCompletionStatus阻塞调用,如果是短连接的话,此处就不需要再投递WSARecv重叠操作了,直接调用GetQueuedCompletionStatus收取另一个客户端连接发送过来的数据就可以了。我刚开始也忽略了这一点,导致程序每次只能收取客户端的第一个请求,后面就再也收不到了。
IOCP

完成IO使用总结IOCP(I/O Completion Port,I/O完成端口)是性能最好的一种I/O模型。
它是应用程序使用线程池处理异步I/O请求的一种机制。
在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建一个线程来应答请求。
这样就有很多的线程并行地运行在系统中。
而这些线程都是可运行的,Windows内核花费大量的时间在进行线程的上下文切换,并没有多少时间花在线程运行上。
再加上创建新线程的开销比较大,所以造成了效率的低下。
调用的步骤如下:抽象出一个完成端口大概的处理流程:1:创建一个完成端口。
2:创建一个线程A。
3:A线程循环调用GetQueuedCompletionStatus()函数来得到IO操作结果,这个函数是个阻塞函数。
4:主线程循环里调用accept等待客户端连接上来。
5:主线程里accept返回新连接建立以后,把这个新的套接字句柄用CreateIoCompletionPort 关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用,因为是异步函数,WSASend/WSARecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。
6:主线程继续下一次循环,阻塞在accept这里等待客户端连接。
7:WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。
8:A线程里的GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WSARecv的结果。
9:在A线程里对这些数据进行处理(如果处理过程很耗时,需要新开线程处理),然后接着发出WSASend/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。
归根到底概括完成端口模型一句话:我们不停地发出异步的WSASend/WSARecv IO操作,具体的IO处理过程由WINDOWS系统完成,WINDOWS系统完成实际的IO处理后,把结果送到完成端口上(如果有多个IO 都完成了,那么就在完成端口那里排成一个队列)。
DELPHI高性能大容量SOCKET并发

DELPHI高性能大容量SOCKET并发(一):IOCP完成端口例子介绍例子主要包括IOCP控件封装、服务端实现、传输协议和日志、控制、SQL查询、上传、下载等协议实现,并包括一些初步的性能测试结果。
服务端:界面截图如下:提供服务和桌面方式运行,桌面方式可直接打开程序,方便日常调试,可以使用命令行注册或卸载服务,在CMD中输入D:\DEMO\IOCPDemo\Bin\IOCPDemoSvr.exe -install来注册服务,在CMD输入D:\DEMO\IOCPDemo\Bin\IOCPDemoSvr.exe -uninstall来卸载服务。
客户端:界面截图如下:主要实现了服务端日志查看,服务端协议类表查看,SQL语句执行协议,上传、下载协议实现,其中对上传、下载实现了一个多线程同时传,用于测试服务器并发性能。
性能:支持超过2000个链接及以上同时上传文件,不过每个连接上传速度只有1到2K。
支持超过2W个连接同时在线传输命令。
单实例上传下载测试结果:从测试结果可以看出随着发送包增大,速度变快。
这里存在一个风险,就是SOCKET传输失败的次数也会增加。
(二):IOCP完成端口控件封装IOCP完成端口介绍:完成端口模型是Windows平台下SOCKET端口模型最为复杂的一种I/O模型。
如果一个应用程序需要同时管理为数众多的套接字,而且希望随着系统内安装的CPU数量的增多,应用程序的性能也可以线性提升,采用完成端口模型,往往可以达到最佳的系统性能。
完成端口可以管理成千上万的连接,长连接传文件可以支持5000个以上,长连接命令交互可以支持20000个以上。
这么大并发的连接,更需要考虑的是应用场景,按照100M的网卡传输速度12.5MB/S,如果是5000个传文件连接,则每个连接能分到的速度2.56KB/S;如果是20000个命令交互连接,则每个连接分到的吞吐量是655B/S,这种速度的吞吐量对很多应用是不满足,这时就要考虑加大网卡的传输速度或实现水平扩展,这个我们后续会介绍。
IOCP完全解析

DWORD Flags = 0; // 单 I/O 操作数据 LPPER_IO_DATA PerIoData = NULL; PerIoData = (LPPER_IO_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_DATA)); ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED)); PerIoData->DataBuf.len = 1024; PerIoData->DataBuf.buf = PerIoData->buffer; PerIoData->OperationType = 0; // read WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL); } /**/////////////////////////////////////////////////////////////////////////// return nRetCode; } /**/////////////////////////////////////////////////////////////////////////// DWORD WINAPI ServerWorkerThread(LPVOID lpParam) { HANDLE CompletionPort = (HANDLE)lpParam; DWORD BytesTransferred; LPOVERLAPPED lpOverlapped; LPPER_HANDLE_DATA PerHandleData = NULL; LPPER_IO_DATA PerIoData = NULL; DWORD SendBytes; DWORD RecvBytes; DWORD Flags; BOOL bRet = FALSE; while (TRUE) { bRet = GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (PULONG_PTR) &PerHandleData,
IOCP完成端口详解(10年吐血大总结)

IOCP完成端口超级详解目录:1.完成端口的优点2.完成端口程序的运行演示3.完成端口的相关概念4.完成端口的基本流程5.完成端口的使用详解6.实际应用中应该要注意的地方一.完成端口的优点1. 我想只要是写过或者想要写C/S模式网络服务器端的朋友,都应该或多或少的听过完成端口的大名吧,完成端口会充分利用Windows内核来进行I/O的调度,是用于C/S 通信模式中性能最好的网络通信模型,没有之一;甚至连和它性能接近的通信模型都没有。
2. 完成端口和其他网络通信方式最大的区别在哪里呢?(1) 首先,如果使用“同步”的方式来通信的话,这里说的同步的方式就是说所有的操作都在一个线程内顺序执行完成,这么做缺点是很明显的:因为同步的通信操作会阻塞住来自同一个线程的任何其他操作,只有这个操作完成了之后,后续的操作才可以完成;一个最明显的例子就是咱们在MFC的界面代码中,直接使用阻塞Socket调用的代码,整个界面都会因此而阻塞住没有响应!所以我们不得不为每一个通信的Socket都要建立一个线程,多麻烦?这不坑爹呢么?所以要写高性能的服务器程序,要求通信一定要是异步的。
(2) 各位读者肯定知道,可以使用使用“同步通信(阻塞通信)+多线程”的方式来改善(1)的情况,那么好,想一下,我们好不容易实现了让服务器端在每一个客户端连入之后,都要启动一个新的Thread和客户端进行通信,有多少个客户端,就需要启动多少个线程,对吧;但是由于这些线程都是处于运行状态,所以系统不得不在所有可运行的线程之间进行上下文的切换,我们自己是没啥感觉,但是CPU却痛苦不堪了,因为线程切换是相当浪费CPU时间的,如果客户端的连入线程过多,这就会弄得CPU都忙着去切换线程了,根本没有多少时间去执行线程体了,所以效率是非常低下的,承认坑爹了不?(3) 而微软提出完成端口模型的初衷,就是为了解决这种"one-thread-per-client"的缺点的,它充分利用内核对象的调度,只使用少量的几个线程来处理和客户端的所有通信,消除了无谓的线程上下文切换,最大限度的提高了网络通信的性能,这种神奇的效果具体是如何实现的请看下文。
完成端口

Windows socket之IO完成端口(IOCP)模型开发IO完成端口是一种内核对象。
利用完成端口,套接字应用程序能够管理数百上千个套接字。
应用程序创建完成端口对象后,通过指定一定数量的服务线程,为已经完成的重叠IO操作提供服务。
该模型可以达到最后的系统性能。
完成端口是一种真正意义上的异步模型。
在重叠IO模型中,当Windows socket应用程序在调用WSARecv函数后立即返回,线程继续运行。
另一线程在在完成端口等待操作结果,当系统接收数据完成后,会向完成端口发送通知,然后应用程序对数据进行处理。
为了将Windows打造成一个出色的服务器环境,Microsoft开发出了IO完成端口。
它需要与线程池配合使用。
服务器有两种线程模型:串行和并发模型。
串行模型:单个线程等待客户端请求。
当请求到来时,该线程被唤醒来处理请求。
但是当多个客户端同时向服务器发出请求时,这些请求必须依次被请求。
并发模型:单个线程等待请求到来。
当请求到来时,会创建新线程来处理。
但是随着更多的请求到来必须创建更多的线程。
这会导致系统内核进行上下文切换花费更多的时间。
线程无法即时响应客户请求。
伴随着不断有客户端请求、退出,系统会不断新建和销毁线程,这同样会增加系统开销。
而IO完成端口却可以很好的解决以上问题。
它的目标就是实现高效服务器程序。
与重叠IO相比较重叠IO与IO完成端口模型都是异步模型。
都可以改善程序性能。
但是它们也有以下区别:1:在重叠IO使用事件通知时,WSAWaitForMultipleEvents 只能等待WSA_MAXIMUM_WAIT_EVENTS(64)个事件。
这限制了服务器提供服务的客户端的数量。
2:事件对象、套接字和WSAOVERLAPPED结构必须一一对应关系,如果出现一点疏漏将会导致严重的后果。
完成端口模型实现包括以下步骤:1:创建完成端口2:将套接字与完成端口关联。
3:调用输入输出函数,发起重叠IO操作。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
矿产资源开发利用方案编写内容要求及审查大纲
矿产资源开发利用方案编写内容要求及《矿产资源开发利用方案》审查大纲一、概述
㈠矿区位置、隶属关系和企业性质。
如为改扩建矿山, 应说明矿山现状、
特点及存在的主要问题。
㈡编制依据
(1简述项目前期工作进展情况及与有关方面对项目的意向性协议情况。
(2 列出开发利用方案编制所依据的主要基础性资料的名称。
如经储量管理部门认定的矿区地质勘探报告、选矿试验报告、加工利用试验报告、工程地质初评资料、矿区水文资料和供水资料等。
对改、扩建矿山应有生产实际资料, 如矿山总平面现状图、矿床开拓系统图、采场现状图和主要采选设备清单等。
二、矿产品需求现状和预测
㈠该矿产在国内需求情况和市场供应情况
1、矿产品现状及加工利用趋向。
2、国内近、远期的需求量及主要销向预测。
㈡产品价格分析
1、国内矿产品价格现状。
2、矿产品价格稳定性及变化趋势。
三、矿产资源概况
㈠矿区总体概况
1、矿区总体规划情况。
2、矿区矿产资源概况。
3、该设计与矿区总体开发的关系。
㈡该设计项目的资源概况
1、矿床地质及构造特征。
2、矿床开采技术条件及水文地质条件。