【重叠I/O之系列三】I/O完成端口
一 串行模式和并行模式
一般一个服务应用程序采用以下两个架构模型之一:
- 串行模式 一个线程等待一个客户发出的请求,当请求到达的时候,线程会被换醒来处理客户的请求。
- 并发模式。一个线程等待一个客户发出的请求,当请求到达的时候,线程会创建一个新的线程来处理客户的请求,而当前线程则会进入下一次循环继续等待客户的请求。
在当前多客户请求的环境下,串行模式远远不能满足当前服务器的性能要求。串行模式每次只能处理一个客户请求,而现在的计算机大多数都是多处理器的机器,所以不充分发挥出多处理器机器的优势。所以串行模式只能应用于一些简单的服务器应用程序,向Ping服务器程序。
由于串行模式的受限,所以在服务器应用中一般采用并发模式。在并发模式中,当服务器接受到一个客户请求时,会创建一个新的线程来处理客户请求。这种模式的优点是显而易见的,等待请求的线程只有很少的工作需要做。当客户请求到达的时候,该线程会被唤醒,创建一个新的处理线程,然后继续睡大觉。所以,服务器可以很快的对客户请求进行相应。而同时,每个客户请求都有一个线程来对其进行处理,能够发挥多处理器机器的优势。但是,这并不是没有缺点的:当一个机器中的线程远大于处理器的数目时,频繁的线程切换会极大的浪费CPU的性能。例如,如果有2000个客户请求,当前的并发模型就需要2000个线程来处理请求,每个线程都需要大量的虚拟内存空间。系统默认的每个线程消耗1MB的堆栈空间,则2000个线程消耗2G虚拟地址空间,而且线程上下文的切换会增加页错误,同时会CPU在线程的上下文切换上需要浪费太多的时间,而线程真正得到CPU执行时间很少。同时,虽然创建一个线程的开销相对于创建进程小的多,但是它的开销仍然不小。如果应用程序能够在初始化的时候创建一个线程池,这样当需要调用线程的时候直接从线程池中获取,这样便可以大大的提升性能了。
正是为了解决以上问题,Windows提出了I/O完成端口解决方案,使得我们在线程池中创建有限数量的服务器线程,这个线程池的调用由Windows系统来维护。同时使用大量的套接字或命名管道句柄,让每个句柄都与不通的客户相关联,句柄不和服务器线程配对。当一个重叠的I/O完成后,会被加入到完成队列中,系统会从线程池中唤醒一个线程来处理完成的I/O请求。
二 I/O完成端口解析
1 创建I/O完成端口
创建I/O完成端口调用函数:
HANDLE
WINAPI
CreateIoCompletionPort(
__in HANDLE FileHandle,
__in_opt HANDLE ExistingCompletionPort,
__in ULONG_PTR CompletionKey,
__in DWORD NumberOfConcurrentThreads
);
- FileHandle
FileHandle是要添加到端口中的一个重叠的设备句柄,注意一个I/O完成端口是以OVERLAPPED模式打开的文件句柄的集合。如果创建一个新的I/O完成端口,则此值为INVALID_HANDLE_VALUE,同时参数ExistingCompletionPort为空。
- ExistingCompletionPort
ExistingCompletionPort表示文件句柄将要关联的端口。
- CompletionKey
CompletionKey指定在完成包中为FileHandle所包含的键值。这个键值可以指向一个结构的指针,该结构包含包含了诸如操作类型、句柄以及指向数据缓冲区指针等信息。
- NumberOfConcurrentPort
表示允许并发执行的线程的最大数量,超过这个数量的等待端口的线程将保持阻塞状态。如果为0,那么最大的并发执行的线程数就是系统中处理器的数目。当ExistingCompletionPort不为NULL时,这个值会被忽略。
这个函数其实是完成两个任务:一是创建一个I/O完成端口,二是将一个设备与一个I/O完成端口关联起来。只是该函数将所有的参数放到一起,显得有点复杂。我们可以将其进行功能拆分,创建两个小函数来分别完成以上两个任务:
//创建新的I/O完成端口
HANDLE CreateNewCompletionPort(DWORD dwNumOfConcurrentThread)
{ return CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, , dwNumOfConcurrentThread);
} //将设备和IO完成端口相关联
BOOL AssociateDeviceWithCompletionPort(HANDLE hDevice, HANDLE hCompletionPort, DWORD dwCompKey)
{
HANDLE h = CreateIoCompletionPort(hDevice,hCompletionPort,dwCompKey,);
return (h == NULL);
}
【重叠I/O之系列三】I/O完成端口的更多相关文章
- 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gulp专家
系列目录 前端构建大法 Gulp 系列 (一):为什么需要前端构建 前端构建大法 Gulp 系列 (二):为什么选择gulp 前端构建大法 Gulp 系列 (三):gulp的4个API 让你成为gul ...
- Web 开发人员和设计师必读文章推荐【系列三十】
<Web 前端开发精华文章推荐>2014年第9期(总第30期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- MyBatis学习系列三——结合Spring
目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring MyBatis在项目中应用一般都要结合Spring,这一章主要把MyBat ...
- MySQL并发复制系列三:MySQL和MariaDB实现对比
http://blog.itpub.net/28218939/viewspace-1975856/ 并发复制(Parallel Replication) 系列三:MySQL 5.7 和MariaDB ...
- WCF编程系列(三)地址与绑定
WCF编程系列(三)地址与绑定 地址 地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...
- 【JAVA编码专题】 JAVA字符编码系列三:Java应用中的编码问题
这两天抽时间又总结/整理了一下各种编码的实际编码方式,和在Java应用中的使用情况,在这里记录下来以便日后参考. 为了构成一个完整的对文字编码的认识和深入把握,以便处理在Java开发过程中遇到的各种问 ...
- SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型
原文:SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server ...
- VSTO之旅系列(三):自定义Excel UI
原文:VSTO之旅系列(三):自定义Excel UI 本专题概要 引言 自定义任务窗体(Task Pane) 自定义选项卡,即Ribbon 自定义上下文菜单 小结 引言 在上一个专题中为大家介绍如何创 ...
- 系列三VisualSvn Server
原文:系列三VisualSvn Server VisualSvn Server介绍 1 .VisualSvn Server VisualSvn Server是免费的,而VisualSvn是收费的.V ...
随机推荐
- Oracle-数据实现竖排打印
--存放重证评分的数据表create table ZZPFapache2( ZZ_datetime DATE, --时间 ZZ_zongfen INTEGER, --总分 ZZ_shiwan ...
- Exercise: Rot13 Reader
package main import ( "io" "os" "strings" "fmt" ) type rot13 ...
- [支付]银联支付(对jdk有要求,最好直接使用jdk7)
数据打包发送到银联服务端,银联返回一个html页面,打开这个页面会自动跳转到银联的支付界面,支付完成后会有前台通知和后台通知,需要注意的是后台通知地址的ip必须是公网ip(广域网ip).这个时候需要配 ...
- Resharp非常实用的快捷键
Alt+Home 定位到父类.父接口 Alt + End 定位到子类 Ctrl+T 快速在整个解决方案下搜索 类型.方法.文件夹 Alt+Ctrl+Spance 给出提示框 Shift+F ...
- 关于继承MonoBehaviour的一些记录
在开发游戏中,为了减少不必要的代码量,我们经常会继承MonoBehaviour,那么MonoBehaviour内部的内置方法Start.Update等等如果在父类中定义了,在子类中再次定义会发生什么事 ...
- Visual Studio动态代码生成的实现基础
这篇文章讨论以下3个问题: 1.代码生成器应该做什么 2.大多数代码生成器的缺点 3.动态代码生成实现的基础 代码生成器应该做什么? 我认为,目标是加快项目开发,方式是减少重复代码手工操作,实现是用过 ...
- Xcode8适配iOS10.1真机测试
将10.1测试包相关文件存放到指定位置,如图步骤提示: 解压文件:
- BZOJ 1878: [SDOI2009]HH的项链 离线树状数组
1878: [SDOI2009]HH的项链 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- requestCode 和 resultCode .
OK,代码如上,可能这个时候还会有点疑问,关于参数的疑问.直接看android sdk 帮助说得更清楚.我发现网上有些文章还有吧 requestCode 和 resultCode 混淆说明错的. st ...
- Windows 8.1 Hyper-V安装的虚拟机
一.安装Hyper-v Hyper-V内置于Windows 8中,用户无需格外的下载安装文件,只需要到Windows 8的程序管理中将其选中开启功能即可. 具体步骤:控制面板→程序→启用或关闭Wind ...