fbpx
维基百科

IOCP

输入输出完成端口(Input/Output Completion Port,IOCP), 是支持多个同时发生的异步I/O操作的应用程序编程接口,在Windows NT的3.5版本以後[1],或AIX 5版以後[2]Solaris第十版以後,開始支持。

IOCP特别适合C/S模式网络服务器端模型。因为,让每一个socket有一个线程负责同步(阻塞)数据处理,one-thread-per-client的缺点是:一是如果连入的客户多了,就需要同样多的线程;二是不同的socket的数据处理都要线程切换的代价。

原理

通常的办法是,线程池中的工作线程的数量与CPU内核数量相同,以此来最小化线程切换代价。一个IOCP对象,在操作系统中可关联着多个Socket和(或)文件控制端。 IOCP对象内部有一个先进先出(FIFO)队列,用于存放IOCP所关联的输入输出端的服务请求完成消息。请求输入输出服务的进程不接收IO服务完成通知,而是检查IOCP的消息队列以确定IO请求的状态。 (线程池中的)多个线程负责从IOCP消息队列中取走完成通知并执行数据处理;如果队列中没有消息,那么线程阻塞挂起在该队列。这些线程从而实现了负载均衡。

Windows操作系统

IOCP是唯一一个不需要安全属性的Windows内核对象。 这是因为IO完成端口在设计时就是只在一个进程中使用。

使用CreateIoCompletionPort函数创建一个新的IOCP,或把socket或文件句柄与一个已存在的IOCP关联起来。

一个线程,第一次调用GetQueuedCompletionStatus函数时,该线程就成为关联了该IOCP的线程,直到下述三种情形之一发生:

  • 该线程退出;
  • 该线程调用GetQueuedCompletionStatus函数关联到其他的IOCP;
  • 该IOCP被关闭。

即,一个线程在任何时刻最多关联一个IOCP。

线程调用GetQueuedCompletionStatus函数等待放入IOCP的I/O完成包(completion packet)。IOCP拥有一个线程池。阻塞在IOCP上的线程按照后进先出(LIFO)顺序被释放(这是为了减少线程切换的代价);而一个线程的完成包按照先进先出(FIFO)顺序从IOCP的队列中取走。IOCP有一个最大允许并发的线程数量上限,在CreateIoCompletionPort函数中指定,每次I/O完成包在从队列取走前检查关联于该IOCP且正在并发执行的线程数量是否达到该限。因其他原因(如调用SuspendThread函数)而挂起的线程不算作正在执行的线程。CompletionKey(完成键)一般作为“单句柄数据”的结构体(PER_HANDLE_DATA),用来标识是哪个设备的I/O完成操作已经完成。IO重叠结构(Overlapped)一般作为“单IO数据”的结构体(PER_IO_DATA),该结构体的第1个成员为OVERLAPPED结构体,用来标识是设备的具体哪个操作。

线程可以用PostQueuedCompletionStatus函数在IOCP上投寄一个完成包。

关闭IOCP之前,必须先关闭关联在该IOCP之上的所有File Handle或socket。

内部结构

Jeffrey Richter英语Jeffrey Richter说:“完成端口可能是最为复杂的内核对象”。[3] Windows中利用CreateIoCompletionPort命令创建完成端口对象时, 操作系统内部为该对象自动创建了5个数据结构,分别是:

  • 设备列表(Device List): 每当调用CreateIoCompletionPort函数时,操作系统会将该设备句柄添加到设备列表中;每当调用CloseHandle关闭了某个设备句柄时,系统会将该设句柄从设备列表中删除
  • IO完成请求队列(I/O Completion Queue-FIFO):当I/O请求操作完成时,或者调用了PostQueuedCompeltionStatus函数时,操作系统会将I/O请求完成包添加到I/O完成队列中。当操作系统从完成端口对象的等待线程队列中取出一个工作线程时,操作系统会同时从I/O完成队列中取出一个元素(I/O请求完成包。
  • 等待线程队列(WaitingThread List-LIFO):当线程中调用GetQueuedCompletionStatus函数时,操作系统会将该线程压入到等待线程队列中。为了减少线程切换,该队列是LIFO。当I/O完成队列非空,且工作线程并未超出总的并发数时,系统从等待线程队列中取出线程,该线程从自身代码的GetQueuedCompletionStatus函数调用处返回并继续运行。
  • 释放线程队列(Released Thread List):当操作系统从等待线程队列中激活了一个工作线程时,或者挂起的线程重新被激活时,该线程被压入释放线程队列中,也即这个队列的线程处于运行状态。这个队列中的线程有两个出队列的机会:一是当线程重新调用GetQueuedCompletionStatus函数时,线程被添加到等待线程队列中;二是当线程调用其他函数使得线程挂起时,该线程被添加到“暂停线程队列”中。
  • 暂停线程队列(Paused Thread List):释放线程队列中的线程被挂起的时候,线程被压入到“暂停线程队列”中;当挂起的线程重新被唤醒时,从“暂停线程队列”中取出放入到释放线程队列。

參考資料

  1. ^ Windows I/O Completion Ports. [2014-04-11]. (原始内容于2014-03-20). 
  2. ^ Configuring IOCP on AIX 5 and 6. [2014-04-11]. (原始内容于2013-06-30). 
  3. ^ 《Windows via C/C++》 Fifth Edition (December 2007) (Jeffrey Richter and Christophe Nasarre) Page292.

外部連結

  • Article . [2014-04-11]. (原始内容存档于2010-11-01).  by Mark Russinovich.
  • IOCPSOCK(页面存档备份,存于互联网档案馆) - an IOCP implementation of a channel driver for the Tcl language to run on Windows NT/2K/XP/Vista

iocp, 此條目需要擴充, 2014年4月11日, 请協助改善这篇條目, 更進一步的信息可能會在討論頁或扩充请求中找到, 请在擴充條目後將此模板移除, 此條目需要精通或熟悉相关主题的编者参与及协助编辑, 2014年4月11日, 請邀請適合的人士改善本条目, 更多的細節與詳情請參见討論頁, 输入输出完成端口, input, output, completion, port, 是支持多个同时发生的异步i, o操作的应用程序编程接口, 在windows, nt的3, 5版本以後, 或aix, 5版以後, 或solari. 此條目需要擴充 2014年4月11日 请協助改善这篇條目 更進一步的信息可能會在討論頁或扩充请求中找到 请在擴充條目後將此模板移除 此條目需要精通或熟悉相关主题的编者参与及协助编辑 2014年4月11日 請邀請適合的人士改善本条目 更多的細節與詳情請參见討論頁 输入输出完成端口 Input Output Completion Port IOCP 是支持多个同时发生的异步I O操作的应用程序编程接口 在Windows NT的3 5版本以後 1 或AIX 5版以後 2 或Solaris第十版以後 開始支持 IOCP特别适合C S模式网络服务器端模型 因为 让每一个socket有一个线程负责同步 阻塞 数据处理 one thread per client的缺点是 一是如果连入的客户多了 就需要同样多的线程 二是不同的socket的数据处理都要线程切换的代价 目录 1 原理 2 Windows操作系统 2 1 内部结构 3 參考資料 4 外部連結原理 编辑通常的办法是 线程池中的工作线程的数量与CPU内核数量相同 以此来最小化线程切换代价 一个IOCP对象 在操作系统中可关联着多个Socket和 或 文件控制端 IOCP对象内部有一个先进先出 FIFO 队列 用于存放IOCP所关联的输入输出端的服务请求完成消息 请求输入输出服务的进程不接收IO服务完成通知 而是检查IOCP的消息队列以确定IO请求的状态 线程池中的 多个线程负责从IOCP消息队列中取走完成通知并执行数据处理 如果队列中没有消息 那么线程阻塞挂起在该队列 这些线程从而实现了负载均衡 Windows操作系统 编辑IOCP是唯一一个不需要安全属性的Windows内核对象 这是因为IO完成端口在设计时就是只在一个进程中使用 使用CreateIoCompletionPort函数创建一个新的IOCP 或把socket或文件句柄与一个已存在的IOCP关联起来 一个线程 第一次调用GetQueuedCompletionStatus函数时 该线程就成为关联了该IOCP的线程 直到下述三种情形之一发生 该线程退出 该线程调用GetQueuedCompletionStatus函数关联到其他的IOCP 该IOCP被关闭 即 一个线程在任何时刻最多关联一个IOCP 线程调用GetQueuedCompletionStatus函数等待放入IOCP的I O完成包 completion packet IOCP拥有一个线程池 阻塞在IOCP上的线程按照后进先出 LIFO 顺序被释放 这是为了减少线程切换的代价 而一个线程的完成包按照先进先出 FIFO 顺序从IOCP的队列中取走 IOCP有一个最大允许并发的线程数量上限 在CreateIoCompletionPort函数中指定 每次I O完成包在从队列取走前检查关联于该IOCP且正在并发执行的线程数量是否达到该限 因其他原因 如调用SuspendThread函数 而挂起的线程不算作正在执行的线程 CompletionKey 完成键 一般作为 单句柄数据 的结构体 PER HANDLE DATA 用来标识是哪个设备的I O完成操作已经完成 IO重叠结构 Overlapped 一般作为 单IO数据 的结构体 PER IO DATA 该结构体的第1个成员为OVERLAPPED结构体 用来标识是设备的具体哪个操作 线程可以用PostQueuedCompletionStatus函数在IOCP上投寄一个完成包 关闭IOCP之前 必须先关闭关联在该IOCP之上的所有File Handle或socket 内部结构 编辑 Jeffrey Richter 英语 Jeffrey Richter 说 完成端口可能是最为复杂的内核对象 3 Windows中利用CreateIoCompletionPort命令创建完成端口对象时 操作系统内部为该对象自动创建了5个数据结构 分别是 设备列表 Device List 每当调用CreateIoCompletionPort函数时 操作系统会将该设备句柄添加到设备列表中 每当调用CloseHandle关闭了某个设备句柄时 系统会将该设句柄从设备列表中删除 IO完成请求队列 I O Completion Queue FIFO 当I O请求操作完成时 或者调用了PostQueuedCompeltionStatus函数时 操作系统会将I O请求完成包添加到I O完成队列中 当操作系统从完成端口对象的等待线程队列中取出一个工作线程时 操作系统会同时从I O完成队列中取出一个元素 I O请求完成包 等待线程队列 WaitingThread List LIFO 当线程中调用GetQueuedCompletionStatus函数时 操作系统会将该线程压入到等待线程队列中 为了减少线程切换 该队列是LIFO 当I O完成队列非空 且工作线程并未超出总的并发数时 系统从等待线程队列中取出线程 该线程从自身代码的GetQueuedCompletionStatus函数调用处返回并继续运行 释放线程队列 Released Thread List 当操作系统从等待线程队列中激活了一个工作线程时 或者挂起的线程重新被激活时 该线程被压入释放线程队列中 也即这个队列的线程处于运行状态 这个队列中的线程有两个出队列的机会 一是当线程重新调用GetQueuedCompletionStatus函数时 线程被添加到等待线程队列中 二是当线程调用其他函数使得线程挂起时 该线程被添加到 暂停线程队列 中 暂停线程队列 Paused Thread List 释放线程队列中的线程被挂起的时候 线程被压入到 暂停线程队列 中 当挂起的线程重新被唤醒时 从 暂停线程队列 中取出放入到释放线程队列 參考資料 编辑 Windows I O Completion Ports 2014 04 11 原始内容存档于2014 03 20 Configuring IOCP on AIX 5 and 6 2014 04 11 原始内容存档于2013 06 30 Windows via C C Fifth Edition December 2007 Jeffrey Richter and Christophe Nasarre Page292 外部連結 编辑Article Inside I O Completion Ports 2014 04 11 原始内容存档于2010 11 01 by Mark Russinovich IOCPSOCK 页面存档备份 存于互联网档案馆 an IOCP implementation of a channel driver for the Tcl language to run on Windows NT 2K XP Vista 取自 https zh wikipedia org w index php title IOCP amp oldid 63130122, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。