IOCP Internals
Buffer Type
Buffer I/O
针对Buffer I/O的请求,系统会为其分配一个非换页内存作为缓存区,其大小等同于I/O请求的缓存区大小。对于写操作,I/O管理器在创建IRP时,将请求者的缓存区数据拷贝到申请得到的非换页缓存区中。对于读操作,I/O管理器将会在I/O完成时,将数据从非换页内存缓存区中拷贝到请求者的缓存区中。在I/O完成后,会释放掉该次申请到的非换页缓存区。
Direct I/O
I/O管理器在处理Direct I/O类型的请求时,会将请求者的缓存区锁定在内存中,使其变成不可换页的内存。当该I/O处理完成时,I/O管理器会解除请求者缓存区的锁定。I/O管理器用MDL机制锁定请求的缓存区,在需要操作缓存区的时候,可以使用相应的API映射请求者的缓存区到系统的地址空间。
Neither I/O
对于此种I/O请求,I/O管理器不会执行任何缓存区管理,对应的缓存管理交给相应的设备驱动程序自己处理。但是不管设备驱动程序如何处理,都不会超过上面两种方式的处理。
I/O Type
Synchronous I/O
应用程序发出的大部分I/O操作是同步的。在设备处理I/O请求时,应用程序需要一直等待,直到I/O完成时,设备返回结果,最终程序才可以继续执行。并且可以立即访问这些被传输的数据。
Asynchronous I/O
异步I/O是程序先发出一个I/O请求,交由设备处理,程序可以继续执行。该程序可以在处理其他事务后检查I/O是否完成,或者当I/O完成时,I/O管理器主动告诉程序I/O已完成。 为了在WINDOWS使用异步I/O,打开文件或建立SOCKET时,需要指定FILE_FLAG_OVERLAPPED标志。
在发起一个异步I/O请求后,必须十分小心:在I/O未完成时,不能访问该I/O操作中任何数据,要确保缓存区有效。发起异步I/O后,为了拿到最终有效的数据,需要做同步操作,WINDOWS下支持OVERLAPPED,也就是基于EVENT内核对象同步,APC(异步过程调用)还有IOCP(I/O Completion Port)。
I/O Completion Process
当一个设备处理完I/O请求时,会调用内核API IoCompleteRequest,通知I/O管理器自己完成了该I/O请求。为了安全操作用户的缓存区,I/O管理器会根据I/O请求类型会执行相应的动作:如果是同步I/O请求,那么可以直接操作请求的缓存区;如果是异步I/O请求,I/O管理器会延迟该I/O完成动作直到请求者对应的地址空间为止。完成该动作的方式是向该请求的线程投递一个APC。在切换到该请求的I/O请求所在的线程时,该APC会得到执行。会把已完成的I/O请求中得到的数据拷贝到对应的缓存区中。这个时候,对于异步I/O请求,像ReadFileEx/WriteFileEx可以投递一个APC例程,I/O管理器在执行I/O完成最后一步后,检测到有APC,就把该APC例程投递到请求线程内,当线程处于警告状态时(SleepEx, WaitForSingleObjectEx)会得到执行。如果该异步I/O请求对应的文件对象或者SOCKET绑定了IOCP,则会在处理完成时,把对应的OVERLAPPED结构投递到IOCP队列中。 这也就是当处理WSARecv时(假设该请求的SOCKET已经绑定了IOCP),如果这个时候系统中已经缓存了数据,这个时候不需要判断是否接收到数据,而只需要判断LastError是否是ERROR_IO_PENDING的原因。
IOCP
在实现服务端程序时,常用的一个简单处理网络请求的方式是针对连接分配一个线程单独处理。太少或太多都会带来性能问题。线程太少,对于客户端的请求无法及时处理;太多,会导致线程频繁轮换。理想的情形是,在服务器的每个处理器上都有一个线程在积极的处理一个用户的请求,如果有其他的请求在等待的话,会立刻有线程来处理这些请求。为了达到这一最优过程得以最终正确的进行,需要有一个办法,能够在处理客户请求的线程在I/O阻塞时,能激活另一个线程处理其他请求。
WINDOWS中引入了IOCP机制来实现这一最优过程。IOCP的内部是依靠一个叫队列的内核对象完成这一过程。当创建一个文件句柄或者SOCKET时,可以把句柄与IOCP句柄绑定在一块,任何以此句柄发起的异步I/O请求操作在完成时都会生成一个CompletionPackage,并把该CompletionPackage排队到该完成端口上,也就是排队到内部的队列内核对象上。应用程序可以通过API GetQueuedCompletionStatus获取已完成的CompletionPackage,处理已完成的I/O数据。
WINDOWS API中的WaitForMultipleObjects函数提供了类似的功能,但是,完成端口的好处是,在系统协助下并发是可控的。处理方式是应用程序主动处理客户端请求的线程的数量。前面提到,理想情况是每个处理器都由一个线程在处理客户端请求。在创建IOCP时,会制定一个值,这个值为关注IOCP的线程数。因为IOCP的内部机制依赖于队列内核对象,在WINDOWS中,内核对象都是可等待的,也就是用类似WaitForSingleObject类似的机制。而IOCP在创建时制定的值会传给内部的队列内核对象作为一个并发值。如果与IOCP关联的活动线程的数量超过了这个并发值,那么正在该IOCP上等待的线程将不允许运行。当有异步I/O完成时,会投递CompletionPackage到绑定的IOCP中的队列对象中,如果此时有线程正在等待,则会直接把这个CompletionPackage交给这个正在等待的线程处理。这样的过程中,没有线程环境切换,更好的把CPU的能力利用起来。
关于IOCP的并发值,Microsoft的指导原则是,将并发值设置成大约等于该系统中处理器的数目。
参考文档:
- 《深入解析Windows操作系统第四版》
- Windows Research Kernel
IOCP Internals的更多相关文章
- iocp 小例子
2016-08-3116:44:09 server 端 /******************************************************************* aut ...
- 简单说一个IOCP不好的地方
感谢rulary的指正!博文中我对IOCP的理解是有误的,正确的方式请见评论区rulary的回复! 由于项目实际设计的需要,最终IO事件处理没有采用IOCP,而是采用了NT6.0引入的WSAPoll, ...
- IOCP和WSA异步协同客户端版
有些小伙伴看了之前发的WIN平台下IOCP和WSA异步协同处理SOCKET后有些疑惑,所以就画了个简易流程图+架构图发上来给小伙伴参考 简单说,WSA异步控制CONNECT,IOCP控制WSASend ...
- windows WSABUF 结构在IOCP 中应用时两个成员变量的意义
WSABUF 结构的原型如下: typedef struct __WSABUF { u_long len; char FAR *buf; } WSABUF, *LPWSABUF; 该结构在IOCP 中 ...
- IOCP入门
完成端口(Completion Port)详解 此文讲解最好,也很全面一下其他文章看看就行,也可不看. 单句柄数据,单IO数据 此文讲述比较清晰,可以辅助理解上文. IOCP编程之基本原理:http: ...
- 解剖SQLSERVER 完结篇 关于Internals Viewer源代码
解剖SQLSERVER 完结篇 关于Internals Viewer源代码 大家可能都用过Internals Viewer这个软件 <查看SQLSERVER内部数据页面的小插件Internals ...
- Key Components and Internals of Spring Boot Framework--转
原文地址:http://www.journaldev.com/7989/key-components-and-internals-of-spring-boot-framework In my prev ...
- iocp还是select
上一个项目libevent应该是select,现在libuv是iocp,都知道Windows下iocp比select效率高,boost asio 也是iocp,但具体使用select和iocp发现没有 ...
- 再谈select, iocp, epoll,kqueue及各种I/O复用机制
原文:http://blog.csdn.net/shallwake/article/details/5265287 首先,介绍几种常见的I/O模型及其区别,如下: blocking I/O nonbl ...
随机推荐
- 【AR实验室】ARToolKit之Example篇
0x00 - 前言 PS : 我突然意识到ARToolKit本质可能就是一个可以实时求解相机内外参的解决方案. 拿到一个新的SDK,90%的人应该都会先跑一下Example.拿到ARToolKit的S ...
- 谈谈一些有趣的CSS题目(十一)-- reset.css 知多少?
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 【原】nodejs全局安装和本地安装的区别
来微信支付有2年多了,从2年前的互联网模式转变为O2O模式,主要的场景是跟线下的商户去打交道,不像以往的互联网模式,有产品经理提需求,我们帮忙去解决问题. 转型后是这样的,团队成员更多需要去寻找业务的 ...
- WPF 微信 MVVM 【续】修复部分用户无法获取列表
看过我WPF 微信 MVVM这篇文章的朋友,应该知道我里面提到了我有一个小号是无法获取列表的,始终也没找到原因. 前两天经过GitHub上h4dex大神的指导,知道了原因,是因为微信在登录以后,web ...
- CSS浮动、定位
这几天有空,整理了关于CSS浮动和定位的一些知识点,有什么欠缺的地方,欢迎大家批评指正. 一.文档流的概念指什么?有哪种方式可以让元素脱离文档流? 文档流,指的是元素排版布局过程中,元素会自动从左往右 ...
- 卡片抽奖插件 CardShow
这个小项目(卡片秀)是一个卡片抽奖特效插件,用开源项目这样的词语让我多少有些羞愧,毕竟作为一个涉世未深的小伙子,用项目的标准衡量还有很大差距.不过该案例采用 jQuery 插件方式编写,提供配置参数并 ...
- QT5利用chromium内核与HTML页面交互
在QT5.4之前,做QT开发浏览器只能选择QWebkit,但是有过使用的都会发现,这个webkit不是出奇的慢,简直是慢的令人发指,Release模式下还行,debug下你就无语了,但是webkit毕 ...
- Effective前端2:优化html标签
div { float: left; } .keyboard > div + div { margin-left: 8px; } --> div{display:table-cell;ve ...
- Android 算法 关于递归和二分法的小算法
// 1. 实现一个函数,在一个有序整型数组中二分查找出指定的值,找到则返回该值的位置,找不到返回 -1. package demo; public class Mytest { public st ...
- DockerCon 2016 – 微软带来了什么?
根据Forrester的调查,接近半数的企业CIO在考虑IT架构的时候更乐于接受开源方案,这主要是基于低成本,避免供应商锁定和敏捷的需求:同时另外一家North Bridge的调研机构的调查显示,20 ...