IOCP完成端口原理

合集下载

名词解释IOCP简介四-Read

名词解释IOCP简介四-Read

hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
该语句的作用是返回一个句柄,在为完成端口分配了一个套接字句柄后,用来对那个 端口进行标定(引用)。
函数功能:注意该函数实际用于两个明显有别的目的: 1. 用于创建一个完成端口对象。 2. 将一个句柄同完成端口关联到一起。
IOCP简介

IOCP的开发
1、CreateIoCompletionPort
最开始创建一个完成端口时,唯一感兴趣的参数便是 NumberOfConcurrentThreads(并发线程的数量);前面三个参数都会被忽略。 NumberOfConcurrentThreads参数的特殊之处在于,它定义了在一个完成端口上, 同时允许执行的线程数量。理想情况下,我们希望每个处理器各自负责一个线程的运 行,为完成端口提供服务,避免过于频繁的线程“场景”切换。若将该参数设为0Байду номын сангаас 表明系统内安装了多少个处理器,便允许同时运行多少个线程!可用下述代码创建一 个I/O完成端口:
IOCP简介

IOCP的应用
可以看出完成端口是到目前为止最为复杂的输入输出模式。然而,当一个 应用不得不同时处理大量的socket时,它也提供了使系统性能达到最佳的可 能性。只有在被迫面对几百甚至几千个并发的socket、你又希望在添加CPU 后可以获得更好的scale时,才被派上战场。关于完成端口,最重要的是记住 这一点:如果你为winnt/2000开发处理大量socket I/O 请求的高性能服 务,它是你的最佳选择 IOCP不仅仅在通信socket上,同时也可以用于其他方面,例如读写文件, 比如把文件句柄关联到完成端口上,产生一定量的工作器线程,读取文件不同 的部分实际读取数据是系统内部处理,只是读取完了通知一下,并且把相关I O数据填充到结构体中

IOCP模型总结

IOCP模型总结

IOCP模型总结
IOCP模型的基本原理是使用操作系统提供的一个输入/输出完成端口,服务器在等待I/O完成时可以继续处理其他的请求(非阻塞),当操作系
统I/O操作完成之后,会通过回调函数的方式通知服务器,从而让服务器
能够及时处理已完成的请求。

2. 创建工作线程(CreateThread):服务器需要创建一定数量的工
作线程,用于处理来自客户端的请求和处理完成端口的通知。

这些工作线
程会在每一个请求到来时进行处理,当有I/O操作完成时,通过回调函数
的方式通知工作线程进行处理。

1.高吞吐量:通过多线程异步I/O的方式,充分利用了硬件性能和操
作系统的特性,能够处理大量的并发请求,提高服务器的吞吐量。

2.高性能:由于保持了非阻塞状态,减少了线程的阻塞时间,服务器
能够更快地响应请求,提供更好的性能。

3.可扩展性好:通过使用多线程模型,服务器可以根据需要动态调整
工作线程的数量,以适应不同的负载情况。

4.高并发处理能力:IOCP模型使用操作系统的通知机制,可以同时
处理多个I/O请求,大大提高了服务器的并发处理能力。

5.方便管理和维护:IOCP模型对服务器的管理和维护提供了便利,
通过将I/O完成的通知传递给操作系统,不需要服务器自己去维护和管理
线程,也无需关心线程的创建和销毁等问题。

总之,IOCP模型是一种高性能、高并发的I/O处理模式,通过利用
操作系统的特性和硬件性能,提高了服务器的处理能力。

它广泛应用于网
络服务器、数据库服务器等需要处理并发请求的场景,能够为用户提供更快速、更稳定的服务。

iocp 编程

iocp 编程

IOCP编程什么是IOCPIOCP(Input/Output Completion Ports)是一种高效的异步I/O模型,它在Windows操作系统中提供了对网络编程的支持。

通过使用IOCP,我们可以实现高性能、可伸缩性强的网络应用程序。

在传统的同步I/O模型中,当一个线程在等待数据时,它会被阻塞,直到数据到达。

而在异步I/O模型中,线程不会被阻塞,它可以继续执行其他任务。

IOCP就是基于这种异步I/O模型实现的。

IOCP的工作原理使用IOCP进行编程主要涉及以下几个核心概念:端口(Port)、完成包(Completion Packet)、套接字(Socket)和重叠操作(Overlapped Operation)。

•端口:一个端口代表一个I/O设备或者一个文件。

每个端口都有一个关联的完成端口。

•完成包:完成包是指一个I/O操作完成时所生成的信息块。

它包含了完成的状态、相关参数和返回值等信息。

•套接字:套接字是网络编程中用于进行通信的抽象概念。

•重叠操作:重叠操作是指一次I/O操作请求,在请求发出之后,线程就可以继续执行其他任务了。

IOCP主要通过以下几个步骤来实现异步I/O:1.创建一个完成端口(Completion Port)。

2.创建一个或多个工作者线程(Worker Thread),这些线程用于处理I/O操作。

3.将套接字关联到完成端口上,使得该套接字上的I/O操作能够被异步处理。

4.当有I/O操作完成时,系统会将相关的完成包放入完成队列中。

5.工作者线程从完成队列中获取完成包,并进行相应的处理。

IOCP的优势和适用场景相比于传统的同步阻塞模型,IOCP具有以下几个优势:1.高性能:IOCP能够充分利用CPU资源,提高程序的并发处理能力。

它通过异步I/O模型,使得线程在等待数据时不被阻塞,可以继续执行其他任务,从而充分利用了CPU资源。

2.可伸缩性:IOCP可以轻松地扩展到支持大量的并发连接。

完成端口详细解析

完成端口详细解析

关于完成端口(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模型的原理和工作过程IOCP模型的原理和工作过程如下:原理:IOCP模型的核心原理是利用操作系统提供的异步I/O和内核级事件通知机制。

异步I/O使得应用程序可以在等待I/O完成时继续处理其他任务,而内核级事件通知机制可以使得操作系统在I/O完成后主动通知应用程序。

通过将I/O操作的处理放在操作系统层面,IOCP模型能够实现高并发、高吞吐量的网络通信。

工作过程:1.创建IOCP对象:应用程序首先创建一个IOCP对象,用于和操作系统进行通信。

2.绑定套接字:应用程序将要进行异步I/O操作的套接字与IOCP对象进行关联。

3.接受连接:应用程序使用套接字进行监听,并且接受到客户端连接请求后,将连接套接字与IOCP对象进行关联,从而使得这个连接套接字能够参与IOCP模型的异步I/O操作。

4.发送和接收数据:应用程序通过调用操作系统提供的异步I/O操作函数,发起网络数据的发送和接收操作。

在发送和接收操作完成之前,应用程序可以继续处理其他任务。

5.等待通知:在发送和接收操作完成之后,应用程序会调用一个等待通知的函数,将自己挂起,等待操作系统的通知。

6.I/O完成通知:当操作系统中发生I/O操作完成的事件时,IOCP对象会通知应用程序,并将I/O操作的结果返回给应用程序。

7.处理完成的I/O操作:应用程序在收到I/O完成的通知后,可以根据返回的结果进行相应的处理。

通常会将I/O操作的结果放入一个队列中,以便后续的处理。

8.处理队列中的完成操作:应用程序会不断地从队列中取出已完成的I/O操作,并进行相应的处理。

处理完成的操作后,应用程序可以继续发起新的I/O操作,从而实现不断地进行网络通信。

总结:IOCP模型利用操作系统提供的异步I/O和内核级事件通知机制,将网络通信的I/O操作交给操作系统来处理,从而实现了高并发、高吞吐量的网络通信。

应用程序通过调用操作系统提供的异步I/O函数来发起发送和接收数据的操作,在操作完成前可以继续处理其他任务。

IOCP

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 都完成了,那么就在完成端口那里排成一个队列)。

iocp流程

iocp流程

iocp流程I/O Completion Port (IOCP) 是 Windows 系统提供的一种高效的 I/O 模型,可以大大提高网络编程的效率和性能。

在分析 IOCP 流程之前,首先要了解 IOCP 的一些基本原理和用法。

IOCP 基本原理IOCP 的基本原理是通过 CreateIoCompletionPort 函数创建一个 I/O 完成端口句柄,将相关的操作(如异步 I/O 操作)关联到该句柄上,并通过 GetQueuedCompletionStatus 函数等待 I/O 完成事件的发生,当事件发生后,系统会自动调用已经与完成端口关联的回调函数来处理该事件。

IOCP 使用步骤下面是使用 IOCP 模型进行网络编程的基本步骤:1. 创建 I/O 完成端口句柄使用 CreateIoCompletionPort 函数创建一个 I/O 完成端口句柄,并指定线程池大小(ThreadCount),通常设置为处理器数量的两倍或三倍,具体根据实际情况进行调整,以提高并发处理能力。

2. 创建套接字并绑定到 I/O 完成端口使用 socket 函数创建一个网络套接字,并将其绑定到 I/O 完成端口句柄上,以便在套接字上的 I/O 操作完成时能够自动通知 I/O 完成端口。

3. 提交 I/O 操作使用 WSARecv 和 WSASend 等函数提交 I/O 操作,将 I/O 操作相关的参数(如套接字句柄、缓冲区、长度等)传递给函数,函数会马上返回,操作会在后台异步执行。

4. 获取 I/O 完成事件使用 GetQueuedCompletionStatus 函数从 I/O 完成端口句柄上获取I/O 完成事件,并将相关的参数(如套接字句柄、缓冲区、长度等)传递给回调函数,回调函数会根据事件类型进行相应的处理(如接收数据或发送数据)。

5. 处理 I/O 完成事件在回调函数中,根据写操作或是读操作的不同,调用相应的函数(如WSASend 或 WSARecv)处理 I/O 完成事件,并提交下一轮 I/O 操作,以便继续异步执行。

IOCP完成端口详解(10年吐血大总结)

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"的缺点的,它充分利用内核对象的调度,只使用少量的几个线程来处理和客户端的所有通信,消除了无谓的线程上下文切换,最大限度的提高了网络通信的性能,这种神奇的效果具体是如何实现的请看下文。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

本文主要探讨一下windows平台上的完成端口开发及其与之相关的几个重要的技术概念,这些概念都是与基于IOCP的开发密切相关的,对开发人员来讲,又不得不给予足够重视的几个概念:1) 基于IOCP实现的服务吞吐量2)IOCP模式下的线程切换3)基于IOCP实现的消息的乱序问题。

一、IOCP简介提到IOCP,大家都非常熟悉,其基本的编程模式,我就不在这里展开了。

在这里我主要是把IOCP中所提及的概念做一个基本性的总结。

IOCP的基本架构图如下:如图所示:在IOCP中,主要有以下的参与者:--》完成端口:是一个FIFO队列,操作系统的IO子系统在IO操作完成后,会把相应的IO packet放入该队列。

--》等待者线程队列:通过调用GetQueuedCompletionStatus API,在完成端口上等待取下一个IO packet。

--》执行者线程组:已经从完成端口上获得IO packet,在占用CPU进行处理。

除了以上三种类型的参与者。

我们还应该注意两个关联关系,即:--》IO Handle与完成端口相关联:任何期望使用IOCP的方式来处理IO请求的,必须将相应的IO Handle与该完成端口相关联。

需要指出的时,这里的IO Handle,可以是File的Handle,或者是Socket的Handle。

--》线程与完成端口相关联:任何调用GetQueuedCompletionStatus API的线程,都将与该完成端口相关联。

在任何给定的时候,该线程只能与一个完成端口相关联,与最后一次调用的GetQueuedCompletionStatus为准。

二、高并发的服务器(基于socket)实现方法一般来讲,实现基于socket的服务器,有三种实现的方式(thread per request的方式,我就不提了:)):第一、线程池的方式。

使用线程池来对客户端请求进行服务。

使用这种方式时,当客户端对服务器的连接是短连接(所谓的短连接,即:客户端对服务器不是长时间连接)时,是可以考虑的。

但是,如若客户端对服务器的连接是长连接时,我们需要限制服务器端的最大连接数目为线程池线程的最大数目,而这应用的设计本身来讲,是不好的设计方式,scalability会存在问题。

第二、基于Select的服务器实现。

其本质是,使用Select(操作系统提供的API)来监视连接是否可读,可写,或者是否出错。

相比于前一种方式,Select允许应用使用一个线程(或者是有限几个线程)来监视连接的可读写性。

当有连接可读可写时,应用可以以non-bolock的方式读写socket上的数据。

使用Select的方式的缺点是,当Select所监视的连接数目在千的数量级时,性能会打折扣。

这是因为操作系统内核需要在内部对这些Socket进行轮询,以检查其可读写性。

另一个问题是:应用必须在处理完所有的可读写socket的IO请求之后,才能再次调用Select,进行下一轮的检查,否则会有潜在的问题。

这样,造成的结果是,对一些请求的处理会出现饥饿的现象。

一般common的做法是Select结合Leader-Follower设计模式使用。

不过不管怎样,Select的本质造成了其在Scalability的问题是不如IOCP,这也是很多high-scalabe的服务器采用IOCP的原因。

第三、IOCP实现高并发的服务器。

IOCP是实现high-scalabe的服务器的首选。

其特点我们专门在下一小姐陈述。

三、IOCP开发的几个概念第一、服务器的吞吐量问题。

我们都知道,基于IOCP的开发是异步IO的,也正是这一技术的本质,决定了IOCP所实现的服务器的高吞吐量。

我们举一个及其简化的例子,来说明这一问题。

在网络服务器的开发过程中,影响其性能吞吐量的,有很多因素,在这里,我们只是把关注点放在两个方面,即:网络IO速度与Disk IO速度。

我们假设:在一个千兆的网络环境下,我们的网络传输速度的极限是大概125M/s,而Disk IO的速度是10M/s。

在这样的前提下,慢速的Disk 设备会成为我们整个应用的瓶颈。

我们假设线程A 负责从网络上读取数据,然后将这些数据写入Disk。

如果对Disk的写入是同步的,那么线程A在等待写完Disk的过程是不能再从网络上接受数据的,在写入Disk的时间内,我们可以认为这时候Server的吞吐量为0(没有接受新的客户端请求)。

对于这样的同步读写Disk,一些的解决方案是通过增加线程数来增加服务器处理的吞吐量,即:当线程A从网络上接受数据后,驱动另外单独的线程来完成读写Disk任务。

这样的方案缺点是:需要线程间的合作,需要线程间的切换(这是另一个我们要讨论的问题)。

而IOCP的异步IO本质,就是通过操作系统内核的支持,允许线程A以非阻塞的方式向IO子系统投递IO请求,而后马上从网络上读取下一个客户端请求。

这样,结果是:在不增加线程数的情况下,IOCP 大大增加了服务器的吞吐量。

说到这里,听起来感觉很像是DMA。

的确,许多软件的实现技术,在本质上,与硬件的实现技术是相通的。

另外一个典型的例子是硬件的流水线技术,同样,在软件领域,也有很著名的应用。

好像话题扯远了,呵呵:)第二、线程间的切换问题。

服务器的实现,通过引入IOCP,会大大减少Thread切换带来的额外开销。

我们都知道,对于服务器性能的一个重要的评估指标就是:System\Context Switches,即单位时间内线程的切换次数。

如果在每秒内,线程的切换次数在千的数量级上,这就意味着你的服务器性能值得商榷。

Context Switches/s应该越小越好。

说到这里,我们来重新审视一下IOCP。

完成端口的线程并发量可以在创建该完成端口时指定(即NumberOfConcurrentThreads参数)。

该并发量限制了与该完成端口相关联的可运行线程的数目(就是前面我在IOCP简介中提到的执行者线程组的最大数目)。

当与该完成端口相关联的可运行线程的总数目达到了该并发量,系统就会阻塞任何与该完成端口相关联的后续线程的执行,直到与该完成端口相关联的可运行线程数目下降到小于该并发量为止。

最有效的假想是发生在有完成包在队列中等待,而没有等待被满足,因为此时完成端口达到了其并发量的极限。

此时,一个正在运行中的线程调用GetQueuedCompletionStatus时,它就会立刻从队列中取走该完成包。

这样就不存在着环境的切换,因为该处于运行中的线程就会连续不断地从队列中取走完成包,而其他的线程就不能运行了。

完成端口的线程并发量的建议值就是你系统CPU的数目。

在这里,要区分清楚的是,完成端口的线程并发量与你为完成端口创建的工作者线程数是没有任何关系的,工作者线程数的数目,完全取决于你的整个应用的设计(当然这个不宜过大,否则失去了IOCP的本意:))。

第三、IOCP开发过程中的消息乱序问题。

使用IOCP开发的问题在于它的复杂。

我们都知道,在使用TCP时,TCP 协议本身保证了消息传递的次序性,这大大降低了上层应用的复杂性。

但是当使用IOCP时,问题就不再那么简单。

如下例:三个线程同时从IOCP中读取Msg1, Msg2,与Msg3。

由于TCP本身消息传递的有序性,所以,在IOCP队列内,Msg1-Msg2-Msg3保证了有序性。

三个线程分别从IOCP中取出Msg1,Msg2与Msg3,然后三个线程都会将各自取到的消息投递到逻辑层处理。

在逻辑处理层的实现,我们不应该假定Msg1-Msg2-Msg3顺序,原因其实很简单,在Time 1~Time 2的时间段内,三个线程被操作系统调度的先后次序是不确定的,所以在到达逻辑处理层,Msg1,Msg2与Msg3的次序也就是不确定的。

所以,逻辑处理层的实现,必须考虑消息乱序的情况,必须考虑多线程环境下的程序实现。

在这里,我把消息乱序的问题单列了出来。

其实在IOCP的开发过程中,相比于同步的方式,应该还有其它更多的难题需要解决,这也是与Select 方式相比,IOCP的缺点,实现复杂度高。

结束语:ACE的Proactor Framework,对windows平台的IOCP做了基于Proactor 设计模式的,面向对象的封装,这在一定程度上简化了应用开发的难度,是一个很好的异步IO的开发框架,推荐学习使用。

Reference:Microsoft Technet,Inside I/O Completion Ports在WINDOWS下进行网络服务端程序开发,毫无疑问,Winsock 完成端口模型是最高效的。

Winsock 的完成端口模型借助Widnows的重叠IO和完成端口来实现,完成端口模型懂了之后是比较简单的,但是要想掌握Winsock完成端口模型,需要对WINDOWS下的线程、线程同步,Winsock API以及WI NDOWS IO机制有一定的了解。

如果不了解,推荐几本书:《Inside Windows 2000,《WINDOWS 核心编程》,《WIN32多线程程序设计》、《WINDOWS网络编程技术》。

在去年,我在C语言下用完成端口模型写了一个WEBSERVER,前些天,我决定用C++重写这个WEBSERVER,给这个WEBSER VER增加了一些功能,并改进完成端口操作方法,比如采用AcceptEx来代替accept和使用LOOKASI DE LIST来管理内存,使得WEBSERVER的性能有了比较大的提高。

一:完成端口模型至于完成端口和Winsock完成端口模型的详细介绍,请参见我上面介绍的那几本书,这里只是我个人对完成端口模型理解的一点心得。

首先我们要抽象出一个完成端口大概的处理流程:1:创建一个完成端口。

2:创建一个线程A。

3:A线程循环调用GetQueuedCompletionStatus()函数来得到IO操作结果,这个函数是个阻塞函数。

4:主线程循环里调用accept等待客户端连接上来。

5:主线程里accept返回新连接建立以后,把这个新的套接字句柄用CreateIoCompletionPort关联到完成端口,然后发出一个异步的WSASend或者WSARecv调用,因为是异步函数,WSASend/WSAR ecv会马上返回,实际的发送或者接收数据的操作由WINDOWS系统去做。

6:主线程继续下一次循环,阻塞在accept这里等待客户端连接。

7:WINDOWS系统完成WSASend或者WSArecv的操作,把结果发到完成端口。

8:A线程里的GetQueuedCompletionStatus()马上返回,并从完成端口取得刚完成的WSASend/WS ARecv的结果。

9:在A线程里对这些数据进行处理(如果处理过程很耗时,需要新开线程处理),然后接着发出WSASen d/WSARecv,并继续下一次循环阻塞在GetQueuedCompletionStatus()这里。

相关文档
最新文档