首页 软件 购物 网址 万年历 阅读 | 天天财汇 | 开发教程 头条阅读
图片批量下载器 M3U8下载器 网页批量下载器 图片自动播放器 淘宝下载 屏幕截图器 网页截图器 超级按键
喔哦浏览器 一键清理系统垃圾 天天百宝箱 布谷鸟定时关机 豆豆文本编辑器 木马查杀 显示器测试 好听音乐
TxT小说阅读器 快马文件互传 小说家小说写作助手 FoxFile文件管理器 千寻小说下载 高山文件备份 网速测试 文字转语音大师
股价下载分析器 离线地图下载器 多播视频 漫多多 品妙游戏 打豆豆 俄罗斯方块 果蔬连连看 宠物连连看 美女连连看 五子棋 订制软件
推荐分类: 软件公告 | 焦点关注 | 天天财汇 |
  当前位置: 首页 > 软件公告 > 技术专区 > Windows完成端口编程(转) > 正文显示
  百分百防木马的网页浏览器 网虫浏览器
 翻页: [1]   共1/1页
第1楼: Windows完成端口编程(转)  
   作者: 匿名   发表时间: 2007/7/26 8:59:29   主页:   IP: 保密
1 基本概念设备---windows操作系统上允许通信的任何东西,比如文件、目录、串行口、并行口、邮件槽、命名管道、无名管道、套接字、控制台、逻辑磁盘、物理磁盘等。绝大多数与设备打交道的函数都是CreateFile/ReadFile/WriteFile等。所以我们不能看到**File函数就只想到文件设备。

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

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

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

完成端口---是一种WINDOWS内核对象。完成端口用于异步方式的重叠I/0情况下,当然重叠I/O不一定非使用完成端口不可,还有设备内核对象、事件对象、告警I/0等。但是完成端口内部提供了线程池的管理,可以避免反复创建线程的开销,同时可以根据CPU的个数灵活的决定线程个数,而且可以让减少线程调度的次数从而提高性能。

2 OVERLAPPED数据结构typedef struct _OVERLAPPED {

ULONG_PTR Internal; //被系统内部赋值,用来表示系统状态

ULONG_PTR InternalHigh; //被系统内部赋值,传输的字节数

union {

struct { //和OffsetHigh合成一个64位

DWORD Offset; //的整数,用来表示从文件头部的多少字节开始

DWORD OffsetHigh;//操作,如果不是对文件I/O来操作,则必须设定为0

};

PVOID Pointer;

};

HANDLE hEvent; //如果不使用,就务必设为0,否则请赋一个有效的Event句柄

} OVERLAPPED, *LPOVERLAPPED;

下面是异步方式使用ReadFile的一个例子

OVERLAPPED Overlapped;

Overlapped.Offset=345;

Overlapped.OffsetHigh=0;

Overlapped.hEvent=0;

//假定其他参数都已经被初始化

ReadFile(hFile,buffer,sizeof(buffer),&dwNumBytesRead,&Overlapped);

这样就完成了异步方式读文件的操作,然后ReadFile函数返回,由操作系统做自己的事情吧

下面介绍几个与OVERLAPPED结构相关的函数

等待重叠I/0操作完成的函数

BOOL GetOverlappedResult (

HANDLE hFile,

LPOVERLAPPED lpOverlapped,//接受返回的重叠I/0结构

LPDWORD lpcbTransfer,//成功传输了多少字节数

BOOL fWait //TRUE只有当操作完成才返回,FALSE直接返回,如果操作没有完成,通过调//用GetLastError ( )函数会返回ERROR_IO_INCOMPLETE

);

宏HasOverlappedIoCompleted可以帮助我们测试重叠I/0操作是否完成,该宏对OVERLAPPED结构的Internal成员进行了测试,查看是否等于STATUS_PENDING值。

3 完成端口的内部机制3.1 创建完成端口

完成端口是一个内核对象,使用时他总是要和至少一个有效的设备句柄进行关联,完成端口是一个复杂的内核对象,创建它的函数是:

HANDLE CreateIoCompletionPort(

IN HANDLE FileHandle,

IN HANDLE ExistingCompletionPort,

IN ULONG_PTR CompletionKey,

IN DWORD NumberOfConcurrentThreads

);

通常创建工作分两步:

第一步,创建一个新的完成端口内核对象,可以使用下面的函数:

HANDLE CreateNewCompletionPort(DWORD dwNumberOfThreads)

{

return CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,NULL,dwNumberOfThreads);

};

第二步,将刚创建的完成端口和一个有效的设备句柄关联起来,可以使用下面的函数:

bool AssicoateDeviceWithCompletionPort(HANDLE hCompPort,HANDLE hDevice,DWORD dwCompKey)

{

HANDLE h=CreateIoCompletionPort(hDevice,hCompPort,dwCompKey,0);

return h==hCompPort;

};

说明

1) CreateIoCompletionPort函数也可以一次性的既创建完成端口对象,又关联到一个有效的设备句柄

2) CompletionKey是一个可以自己定义的参数,我们可以把一个结构的地址赋给它,然后在合适的时候取出来使用,最好要保证结构里面的内存不是分配在栈上,除非你有十分的把握内存会保留到你要使用的那一刻。

3) NumberOfConcurrentThreads通常用来指定要允许同时运行的的线程的最大个数。通常我们指定为0,这样系统会根据CPU的个数来自动确定。

创建和关联的动作完成后,系统会将完成端口关联的设备句柄、完成键作为一条纪录加入到这个完成端口的设备列表中。如果你有多个完成端口,就会有多个对应的设备列表。如果设备句柄被关闭,则表中自动删除该纪录。

3.2 完成端口线程的工作原理

完成端口可以帮助我们管理线程池,但是线程池中的线程需要我们使用_beginthreadex来创建,凭什么通知完成端口管理我们的新线程呢?答案在函数GetQueuedCompletionStatus。该函数原型:

BOOL GetQueuedCompletionStatus(

IN HANDLE CompletionPort,

OUT LPDWORD lpNumberOfBytesTransferred,

OUT PULONG_PTR lpCompletionKey,

OUT LPOVERLAPPED *lpOverlapped,

IN DWORD dwMilliseconds

);

这个函数试图从指定的完成端口的I/0完成队列中抽取纪录。只有当重叠I/O动作完成的时候,完成队列中才有纪录。凡是调用这个函数的线程将被放入到完成端口的等待线程队列中,因此完成端口就可以在自己的线程池中帮助我们维护这个线程。

完成端口的I/0完成队列中存放了当重叠I/0完成的结果---- 一条纪录,该纪录拥有四个字段,前三项就对应GetQueuedCompletionStatus函数的2、3、4参数,最后一个字段是错误信息dwError。我们也可以通过调用PostQueudCompletionStatus模拟完成了一个重叠I/0操作。

当I/0完成队列中出现了纪录,完成端口将会检查等待线程队列,该队列中的线程都是通过调用

 

 翻页: [1]   共1/1页



   若有疑问请联系我们

  ※软件公告※
图片批量下载器
获首届软件创新大赛优秀奖
电脑教育报
专访TxT小说阅读器
软件相关
·软件公告
·图片批量下载器
·超级按键
·网虫浏览器
·一键清除系统垃圾
·TxT小说阅读器
·热门小说推荐
·小说下载器
·网页截图器
·木马祼奔
·天天百宝箱
·显示器测试
·图片管理器
·好听音乐盒
·连连看游戏系列
资讯相关
·焦点关注
·在线游戏
·娱乐八卦
·经济论坛
·体育世界
·健康知识
·每日一笑
·技术专区
·特别推荐
·随便贴贴
三石聚峰
Intel软件合作伙伴
·几张很黄很黄的图片
·预测你的未来潜能

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/27 3:48:07-

 网站联系 2006-2024 三石聚峰 WWW.3FWork.COM 蜀ICP备06016416号