- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
IOCP 完成端口详解——VC/VC++
通常要开发网络应用程序并不是一件轻松的事情,不过,实际上只要掌握几个关键的
原则也就可以了——创建和连接一个套接字,尝试进行连接,然后收发数据。真正难的是要
写出一个可以接纳少则一个,多则数千个连接的网络应用程序。本文将讨论如何通过
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 时间,在此期间该线程可以运行,然后另一个线程将分到一个
时间片并开始执行。如果某个线程执行了阻塞型的操作,操作系统将剥夺其未使用的剩余时
间片并让其它线程开始执行。也就是说,前一个线程没有充分使用其时间片,当发生这样的
情况时,应用程序应该准备其它线程来充分利用这些时间片。
完成端口的使用分为两步。首先创建完成端口,如以下代码所示:
HANDLE hIocp;
hIocp = CreateIoCompletionPort(
INVALID_HANDLE_VALUE,
NULL,
(ULONG_PTR)0,
0);
if (hIocp == NULL) {
// Error
}
完成端口创建后,要把将使用该完成端口的套接字与之关联起来。方法是再次调用
CreateIoCompletionPort ()函数,第一个参数 FileHandle 设为套接字的句柄,第二个参数
ExistingCompletionPort 设为刚刚创建的那个完成端口的句柄。
以下代码创建了一个套接字,并把它和前面创建的完成端口关联起来:
SOCKET s;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET) {
// Error
if (CreateIoCompletionPort((HANDLE)s,
hIocp,
(ULONG_PTR)0,
0) == NULL)
{
// Error
}
???
}
这时就完成了套接字与完成端口的关联操作。在这个套接字上进行的任何重叠操作都
将通过完成端口发出完成通知。注意,CreateIoCompletionPort()函数中的第三个参数用来
设置一个与该套接字相关的 “完成键(completion key)”(译者注:完成键可以是任何数据
类型)。每当完成通知到来时,应用程序可以读取相应的完成键,因此,完成键可用来给套
接字传递一些背景信息。
文档评论(0)