WinSock完成端口IO模型.doc

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
WinSock完成端口IO模型

关于重叠I/O,参考《WinSock重叠I/O模型》;关于完成端口的概念及内部机制,参考译文《深度探索I/O完成端口》。 完成端口对象取代了WSAAsyncSelect中的消息驱动和WSAEventSelect中的事件对象,当然完成端口模型的内部机制要比WSAAsyncSelect和WSAEventSelect模型复杂得多。 IOCP内部机制如下图所示: 在WinSock中编写完成端口程序,首先要调用CreateIoCompletionPort函数创建完成端口。其原型如下: WINBASEAPI HANDLE WINAPI CreateIoCompletionPort( HANDLE FileHandle, HANDLE ExistingCompletionPort, DWORD CompletionKey, DWORD NumberOfConcurrentThreads ); 第一次调用此函数创建一个完成端口时,通常只关注NumberOfConcurrentThreads,它定义了在完成端口上同时允许执行的线程数量。一般设为0,表示系统内安装了多少个处理器,便允许同时运行多少个线程为完成端口提供服务。每个处理器各自负责一个线程的运行,避免了过于频繁的线程上下文切换。 hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0) 这个类比重叠I/O事件通知模型中(WSA)CreateEvent。 然后再调用GetSystemInfo(SystemInfo);取得系统安装的处理器的个数SystemInfo.dwNumberOfProcessors,根据CPU数创建线程池,在完成端口上,为已完成的I/O请求提供服务。一般线程池的规模,即线程数 = CPU数*2+2。 下面的代码片段演示了线程池的创建。 // 创建线程池,规模为CPU数的两倍 for(int i = 0; i SystemInfo.dwNumberOfProcessors * 2; i++) { HANDLE ThreadHandle; // 创建一个工作线程,并将完成端口作为参数传递给它。 if ((ThreadHandle = CreateThread(NULL, 0, WorkerThread, hCompletionPort, 0, ThreadID)) == NULL) { printf(CreateThread() failed with error %d/n, GetLastError()); return; } // 关闭线程句柄 CloseHandle(ThreadHandle); } 然后需要将一个句柄与已经创建的完成端口关联起来,这里主要指套接字AcceptSocket,以后针对这个套接字的I/O完成状态交由完成端口通知,程序接到完成通知后做善后处理。 这需要再次调用CreateIoCompletionPort函数(囧)。参数四NumberOfConcurrentThreads依旧填0,参数一一般就是AcceptSocket,参数二为上面创建的完成端口hCompletionPort。参数三即“完成键”,一般存放套接字句柄的背景信息,也就是所谓的“单句柄数据”。之所以把它叫作“单句柄数据”,因为它是用来保存参数一套接字句柄的关联信息。一般可简单定义如下: typedef struct { SOCKET Socket; } PER_HANDLE_DATA, * LPPER_HANDLE_DATA; 下面的代码片段演示了每次Accept返回时,调用CreateIoCompletionPort使返回的AcceptSocket与完成端口关联,并传递一个PerHandleData。 AcceptSocket = WSAAccept(Listen, NULL, NULL, NULL, 0); PerHandleData-Socket = AcceptSocket; CreateIoCompletionPort((HANDLE) AcceptSocket, hCompletionPort, (DWORD) PerHandleData, 0) 这个类比重叠I/O事件通知模型中设置(WSA)OVERLAPPED结构中的hEvent字段,使一个事件对象句柄同一个文件/套接字关联起来。 将套接字句柄与一个完成端口关联在一起后,便可以套接字句柄为基础,投递发送与接收请求,开始对I/O请求的处理。接下来,可开始依赖完成端口,来接收有关I/O操作完成情况的通知。从本质上说,完成端口模型利用了Win32重叠I/O机制。在这种机制中,像WSARecv()和WSASend()这样的WinS

文档评论(0)

pangzilva + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档