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

完成端口

完成端口

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操作。

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程IOCP(Input/Output Completion Port)模型是一种高效的异步IO 机制,它可以帮助我们更好地处理并发IO请求。

在本文中,我们将详细介绍IOCP模型的原理和工作过程。

一、IOCP模型的基本原理1.1 异步IO在传统的同步IO模型中,当程序调用一个IO操作时,它必须等待该操作完成后才能继续执行后面的代码。

这种方式会导致程序在等待IO 操作完成时出现阻塞,从而浪费了CPU资源。

相比之下,异步IO模型允许程序调用一个IO操作后立即返回,并在后台处理该操作。

当该操作完成时,系统将通知程序,并返回结果。

这种方式可以提高程序的并发性和吞吐量。

1.2 IOCP机制为了更好地支持异步IO,Windows引入了IOCP机制。

它是一种通知机制,可以帮助我们更好地处理异步IO请求。

具体来说,当一个异步IO请求被提交到系统中时,系统会为其分配一个I/O Completion Port(即完成端口)。

当该请求完成时,系统将通知该端口,并返回相关信息。

程序可以通过监听该端口来获取请求完成的通知,并进行相应的处理。

二、 IOCP模型的工作过程2.1 创建I/O Completion Port首先需要创建I/O Completion Port(以下简称IOCP)。

可以通过CreateIoCompletionPort函数来创建一个IOCP。

该函数返回一个句柄,该句柄用于后续的操作。

2.2 将Socket与IOCP关联接下来需要将Socket与IOCP关联。

可以通过CreateIoCompletionPort或者WSAEventSelect函数来实现。

2.3 提交异步IO请求当需要进行异步IO操作时,可以使用WSASend、WSARecv等函数来提交异步IO请求。

这些函数会将请求提交到系统中,并立即返回。

2.4 处理完成通知当一个异步IO请求完成时,系统会向其关联的IOCP发送一个完成通知。

IOCP_原理_代码

IOCP_原理_代码

Windows I/O完成端口WINDOWS完成端口编程1、基本概念2、WINDOWS完成端口的特点3、完成端口(Completion Ports )相关数据结构和创建4、完成端口线程的工作原理5、Windows完成端口的实例代码WINDOWS完成端口编程摘要:开发网络程序从来都不是一件容易的事情,尽管只需要遵守很少的一些规则:创建socket,发起连接,接受连接,发送和接收数据,等等。

真正的困难在于:让你的程序可以适应从单单一个连接到几千个连接乃至于上万个连接。

利用Windows完成端口进行重叠I/O的技术,可以很方便地在Windows平台上开发出支持大量连接的网络服务程序。

本文介绍在Windows平台上使用完成端口模型开发的基本原理,同时给出实际的例子。

本文主要关注C/S结构的服务器端程序,因为一般来说,开发一个大容量、具有可扩展性的winsock程序就是指服务程序。

1、基本概念设备---指windows操作系统上允许通信的任何东西,比如文件、目录、串行口、并行口、邮件槽、命名管道、无名管道、套接字、控制台、逻辑磁盘、物理磁盘等。

绝大多数与设备打交道的函数都是CreateFile/ReadFile/WriteFile 等,所以我们不能看到**File函数就只想到文件设备。

与设备通信有两种方式,同步方式和异步方式:同步方式下,当调用ReadFile这类函数时,函数会等待系统执行完所要求的工作,然后才返回;异步方式下,ReadFile这类函数会直接返回,系统自己去完成对设备的操作,然后以某种方式通知完成操作。

重叠I/O----顾名思义,就是当你调用了某个函数(比如ReadFile)就立刻返回接着做自己的其他动作的时候,系统同时也在对I/0设备进行你所请求的操作,在这段时间内你的程序和系统的内部动作是重叠的,因此有更好的性能。

所以,重叠I/O是在异步方式下使用I/O设备的。

重叠I/O需要使用的一个非常重要的数据结构:OVERLAPPED。

IOCP详解

IOCP详解

IOCP详解简介: IOCP(I/O Completion Port,I/O完成端⼝)是性能最好的⼀种I/O模型。

它是应⽤程序使⽤线程池处理异步I/O请求的⼀种机制。

IOCP详解IOCP(I/O Completion Port,I/O完成端⼝)是性能最好的⼀种I/O模型。

它是应⽤程序使⽤线程池处理异步I/O请求的⼀种机制。

在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建⼀个线程来应答请求。

这样就有很多的线程并⾏地运⾏在系统中。

⽽这些线程都是可运⾏的,Windows内核花费⼤量的时间在进⾏线程的上下⽂切换,并没有多少时间花在线程运⾏上。

再加上创建新线程的开销⽐较⼤,所以造成了效率的低下。

Windows Sockets应⽤程序在调⽤WSARecv()函数后⽴即返回,线程继续运⾏。

当系统接收数据完成后,向完成端⼝发送通知包(这个过程对应⽤程序不可见)。

应⽤程序在发起接收数据操作后,在完成端⼝上等待操作结果。

当接收到I/O操作完成的通知后,应⽤程序对数据进⾏处理。

完成端⼝其实就是上⾯两项的联合使⽤基础上进⾏了⼀定的改进。

⼀个完成端⼝其实就是⼀个通知队列,由操作系统把已经完成的重叠I/O请求的通知放⼊其中。

当某项I/O操作⼀旦完成,某个可以对该操作结果进⾏处理的⼯作者线程就会收到⼀则通知。

⽽套接字在被创建后,可以在任何时候与某个完成端⼝进⾏关联。

众所皆知,完成端⼝是在WINDOWS平台下效率最⾼,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显⽰出其威⼒。

其实建⽴⼀个完成端⼝的服务器也很简单,只要注意⼏个函数,了解⼀下关键的步骤也就⾏了。

分为以下⼏步来说明完成端⼝:0) 同步IO与异步IO1) 函数2) 常见问题以及解答3) 步骤4) 例程0、同步IO与异步IO同步I/O⾸先我们来看下同步I/O操作,同步I/O操作就是对于同⼀个I/O对象句柄在同⼀时刻只允许⼀个I/O操作,原理图如下:由图可知,内核开始处理I/O操作到结束的时间段是T2~T3,这个时间段中⽤户线程⼀直处于等待状态,如果这个时间段⽐较短,则不会有什么问题,但是如果时间⽐较长,那么这段时间线程会⼀直处于挂起状态,这就会很严重影响效率,所以我们可以考虑在这段时间做些事情。

在c#使用IOCP(完成端口)的简单示例

在c#使用IOCP(完成端口)的简单示例

在c#使用IOCP(完成端口)的简单示例这次给大家演示一下利用IOCP的在线程间传递数据的例子,顺便打算讲一些细节和注意的地方。

概述:这里主要使用IOCP的三个API,CreateIoCompletionPort,PostQueuedCompletionStatus,GetQueuedCompletionStatus,第一个是用来创建一个完成端口对象,第二个是向一个端口发送数据,第三个是接受数据,基本上用着三个函数,就可以写一个使用IOCP的简单示例。

其中完成端口一个内核对象,所以创建的时候会耗费性能,CPU得切换到内核模式,而且一旦创建了内核对象,我们都要记着要不用的时候显式的释放它的句柄,释放非托管资源的最佳实践肯定是使用Dispose模式,这个博客园有人讲过N次了。

而一般要获取一个内核对象的引用,最好用SafeHandle来引用它,这个类可以帮你管理引用计数,而且用它引用内核对象,代码更健壮,如果用指针引用内核对象,在创建成功内核对象并复制给指针这个时间段,如果抛了ThreadAbortException,这个内核对象就泄漏了,而用SafeHandle去应用内核对象就不会在赋值的时候发生ThreadAbortException。

另外SafeHandle类继承自CriticalFinalizerObject类,并实现了IDispose接口,CLR对CriticalFinalizerObject及其子类有特殊照顾,比如说在编译的时候优先编译,在调用非CriticalFinalizerObject类的Finalize方法后再调用CriticalFinalizerObject类的Finalize类的Finalize方法等。

在win32里,一般一个句柄是-1或者0的时候表示这个句柄是无效的,所以.net有一个SafeHandle的派生类SafeHandleZeroOrMinusOneIsInvalid ,但是这个类是一个抽象类,你要引用自己使用的内核对象或者非托管对象,要从这个类派生一个类并重写Relseas方法。

第4章 ICOP与可伸缩网络程序

第4章 ICOP与可伸缩网络程序

实现过程:

以下,分为以下几步来说明完成端口模型: 1。函数 2。常见问题 3。步骤 4。例程
函数

我们在完成端口模型下会使用到的最重要的两个 函数是:
(1) CreateIoCompletionPort (2) GetQueuedCompletionStatus
(1) CreateIoCompletionPort函数

从本质上说,完成端口模型要求我们创建一个Wi n 3 2完成端 口对象,通过指定数量的线程,对重叠I / O请求进行管理,以 便为已经完成的重叠I / O请求提供服务。 要注意: 所谓“完成端口”,实际是Wi n 3 2、 Windows NT 以及Windows 2000采用的一种I / O构造机制. 使用这种模型之前,首先要创建一个I / O完成端口对象,用它 面向任意数量的套接字句柄,管理多个I / O请求。 IOCP只不过是用来进行读写操作,和文件I/O有些类似。
结果分析大家可以看到:服务器,勿庸置疑,肯定是完成 端口模式。那么客户端呢,当然也可以采用完成端口,但 是不同模式是在不同的操作系统下支持的,看下图:
完成端口在Windows 98下是不支持的。关键的一点,客户端程 序不是用来进行大规模网络响应的,客户端的主要工作应该是 进行诸如图形运算等非网络方面的任务。所以,强烈推荐大家 使用WSAAsyncSelect/ WSAEvevtSelect模式实现客户端,因为 它实现起来比较直接和容易,而且他完全可以满足客户端编程 的需求。
WSASend函数

int WSASend(
SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

网络程序设计 IOCP与可伸缩网络程序

网络程序设计 IOCP与可伸缩网络程序

网络程序设计 IOCP与可伸缩网络程序网络程序设计: IOCP与可伸缩网络程序1. 简介网络程序设计是指开发一种能够在计算机网络上运行的程序的过程。

在开发网络程序时,有两个重要的概念需要了解:IOCP (Input/Output Completion Ports)和可伸缩网络程序。

IOCP是一种高性能的I/O模型,它通过非阻塞的方式处理I/O 操作,提供了一种高效的方法来管理大量的并发连接。

可伸缩网络程序是一种设计良好的程序,能够优雅地处理高并发请求,并且可以在需要时扩展以应对更高的负载。

本文将详细介绍IOCP和可伸缩网络程序的概念、原理以及如何实现。

2. IOCP的原理IOCP是Windows操作系统提供的一种I/O完成端口技术。

它的核心思想是将I/O操作的完成通知集中管理,而不是像传统的阻塞I/O方式那样在每次I/O操作时等待。

通过使用IOCP,可以实现高效的异步I/O操作,提高系统的并发性能。

IOCP的主要原理是将所有待处理的I/O操作放入一个I/O完成端口中,然后由系统负责监听这个I/O完成端口上的完成通知。

当一个I/O操作完成时,系统会触发相应的回调函数,通知应用程序去处理这个完成事件。

3. 实现可伸缩网络程序可伸缩网络程序的设计是为了能够处理大量的并发连接,保持高性能和低延迟。

下面是一些实现可伸缩网络程序的建议:3.1 使用多线程或多进程可伸缩网络程序通常使用多线程或多进程来处理并发连接。

每个线程或进程负责处理一个或多个连接,这样可以充分利用系统资源,提高并发处理能力。

3.2 使用连接池连接池是一种管理连接的机制,它可以预先创建一定数量的连接并放入池中,当有新的连接请求时,从连接池中取出一个空闲连接来处理请求,处理完毕后再放回连接池中。

3.3 使用非阻塞I/O非阻塞I/O是指在进行I/O操作时,如果没有数据可读或可写,立即返回而不是一直等待。

通过使用非阻塞I/O,可以避免线程或进程因等待I/O而被阻塞,提高系统的并发性能。

理解I O C P(完成端口)

理解I O C P(完成端口)

理解I/O Completion Port(完成端口)欢迎阅读此篇IOCP教程。

我将先给出IOCP的定义然后给出它的实现方法,最后剖析一个Echo 程序来为您拨开IOCP的谜云,除去你心中对IOCP的烦恼。

OK,但我不能保证你明白IOCP 的一切,但我会尽我最大的努力。

以下是我会在这篇文章中提到的相关技术:I/O端口同步/异步堵塞/非堵塞服务端/客户端多线程程序设计Winsock API 2.0在这之前,我曾经开发过一个项目,其中一块需要网络支持,当时还考虑到了代码的可移植性,只要使用select,connect,accept,listen,send还有recv,再加上几个#ifdef的封装以用来处理Winsock和BSD套接字[socket]中间的不兼容性,一个网络子系统只用了几个小时很少的代码就写出来了,至今还让我很回味。

那以后很长时间也就没再碰了。

前些日子,我们策划做一个网络游戏,我主动承担下网络这一块,想想这还不是小case,心里偷着乐啊。

网络游戏好啊,网络游戏为成百上千的玩家提供了乐趣和令人着秘的游戏体验,他们在线上互相战斗或是加入队伍去战胜共同的敌人。

我信心满满的准备开写我的网络,于是乎,发现过去的阻塞同步模式模式根本不能拿到一个巨量多玩家[MMP]的架构中去,直接被否定掉了。

于是乎,就有了IOCP,如果能过很轻易而举的搞掂IOCP,也就不会有这篇教程了。

下面请诸位跟随我进入正题。

什么是IOCP?先让我们看看对IOCP的评价I/O完成端口可能是Win32提供的最复杂的内核对象。

[Advanced Windows 3rd] Jeffrey Richter这是[IOCP]实现高容量网络服务器的最佳方法。

[Windows Sockets2.0:Write Scalable Winsock Apps Using Completion Ports]Microsoft Corporation完成端口模型提供了最好的伸缩性。

IOCP完成端口详解

IOCP完成端口详解

IOCP完成端口详解通常要开发网络应用程序并不是一件轻松的事情,不过,实际上只要掌握几个关键的原则也就可以了——创建和连接一个套接字,尝试进行连接,然后收发数据。

真正难的是要写出一个可以接纳少则一个,多则数千个连接的网络应用程序。

本文将讨论如何通过Winsock2在Windows NT 和Windows 2000上开发高扩展能力的Winsock应用程序。

文章主要的焦点在客户机/服务器模型的服务器这一方,当然,其中的许多要点对模型的双方都适用。

API与响应规模通过Win32的重叠I/O机制,应用程序可以提请一项I/O操作,重叠的操作请求在后台完成,而同一时间提请操作的线程去做其他的事情。

等重叠操作完成后线程收到有关的通知。

这种机制对那些耗时的操作而言特别有用。

不过,像Windows 3.1上的WSAAsyncSelect()及Unix下的select()那样的函数虽然易于使用,但是它们不能满足响应规模的需要。

而完成端口机制是针对操作系统内部进行了优化,在Windows NT 和Windows 2000上,使用了完成端口的重叠I/O机制才能够真正扩大系统的响应规模。

完成端口一个完成端口其实就是一个通知队列,由操作系统把已经完成的重叠I/O请求的通知放入其中。

当某项I/O操作一旦完成,某个可以对该操作结果进行处理的工作者线程就会收到一则通知。

而套接字在被创建后,可以在任何时候与某个完成端口进行关联。

通常情况下,我们会在应用程序中创建一定数量的工作者线程来处理这些通知。

线程数量取决于应用程序的特定需要。

理想的情况是,线程数量等于处理器的数量,不过这也要求任何线程都不应该执行诸如同步读写、等待事件通知等阻塞型的操作,以免线程阻塞。

每个线程都将分到一定的CPU时间,在此期间该线程可以运行,然后另一个线程将分到一个时间片并开始执行。

如果某个线程执行了阻塞型的操作,操作系统将剥夺其未使用的剩余时间片并让其它线程开始执行。

[转]IOCP介绍

[转]IOCP介绍

[转]IOCP介绍IO完成端⼝下⾯摘抄于MSDN《I/O Completion Ports》,smallfool翻译,原⽂请参考CSDN⽂档中⼼⽂章《I/O Completion Ports》,。

I/O完成端⼝是⼀种机制,通过这个机制,应⽤程序在启动时会⾸先创建⼀个线程池,然后该应⽤程序使⽤线程池处理异步I/O请求。

这些线程被创建的唯⼀⽬的就是⽤于处理I/O请求。

对于处理⼤量并发异步I/O请求的应⽤程序来说,相⽐于在I/O请求发⽣时创建线程来说,使⽤完成端⼝(s)它就可以做的更快且更有效率。

CreateIoCompletionPort函数会使⼀个I/O完成端⼝与⼀个或多个⽂件句柄发⽣关联。

当与⼀个完成端⼝相关的⽂件句柄上启动的异步I/O操作完成时,⼀个I/O完成包就会进⼊到该完成端⼝的队列中。

对于多个⽂件句柄来说,这种机制可以⽤来把多⽂件句柄的同步点放在单个对象中。

(⾔下之意,如果我们需要对每个句柄⽂件进⾏同步,⼀般⽽⾔我们需要多个对象(如:Event来同步),⽽我们使⽤IO Complete Port 来实现异步操作,我们可以同多个⽂件相关联,每当⼀个⽂件中的异步操作完成,就会把⼀个complete package放到队列中,这样我们就可以使⽤这个来完成所有⽂件句柄的同步)调⽤GetQueuedCompletionStatus函数,某个线程就会等待⼀个完成包进⼊到完成端⼝的队列中,⽽不是直接等待异步I/O请求完成。

线程(们)就会阻塞于它们的运⾏在完成端⼝(按照后进先出队列顺序的被释放)。

这就意味着当⼀个完成包进⼊到完成端⼝的队列中时,系统会释放最近被阻塞在该完成端⼝的线程。

调⽤GetQueuedCompletionStatus,线程就会将会与某个指定的完成端⼝建⽴联系,⼀直延续其该线程的存在周期,或被指定了不同的完成端⼝,或者释放了与完成端⼝的联系。

⼀个线程只能与最多不超过⼀个的完成端⼝发⽣联系。

iocp 编程 -回复

iocp 编程 -回复

iocp 编程-回复IOCP(Input/Output Completion Ports)编程是一种高效的服务器端编程模型,它利用操作系统级的异步I/O机制,能够实现高性能、高可扩展性和高并发的网络应用程序。

本文将逐步解释IOCP编程,包括其原理、特点、实现方式以及常见应用场景。

一、IOCP编程的原理IOCP编程基于操作系统提供的异步I/O机制,通过操作系统内核中的完成端口(completion port)来实现异步I/O操作的管理和处理。

操作系统将I/O请求和完成事件的管理和调度交给了完成端口,应用程序通过与完成端口进行通信来管理和处理I/O操作。

当应用程序需要进行I/O操作时,它可以向完成端口提交一个I/O请求。

完成端口会将这个请求发送给操作系统的驱动程序,并立即返回给应用程序,不会阻塞应用程序的继续执行。

当I/O操作完成时,操作系统会将完成事件通知完成端口,完成端口再将完成事件通知给应用程序进行处理。

应用程序可以通过从完成端口获取完成事件来获取已完成的I/O操作的结果,而无需进行轮询等待。

通过这种方式,IOCP编程能够高效地处理大量的并发I/O操作,提高服务器性能和可扩展性。

二、IOCP编程的特点1. 高性能:IOCP编程利用了操作系统提供的异步I/O机制,能够实现高效率的I/O操作处理。

相对于传统的同步I/O模型,它能够极大地提升服务器的性能。

2. 高可扩展性:IOCP编程通过使用完成端口进行异步I/O操作的管理和处理,能够很好地适应大量并发连接的场景。

它能够实现更高的并发能力和更低的系统资源开销,使得服务器能够轻松应对高并发请求。

3. 简化了编程模型:相对于传统的多线程或多进程方式处理并发I/O操作的编程模型,IOCP编程可以减少线程和进程的创建和维护的开销,简化了编程模型。

应用程序只需要关注I/O操作提交和完成事件的处理,而不需要关心具体的线程或进程创建和管理。

三、IOCP编程的实现方式IOCP编程可以在不同的操作系统平台上实现,如Windows和Linux。

  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()这里。

相关文档
最新文档