您的位置:首页 > 编程语言

Windows服务器端编程-第二章 设备IO与线程间通信-6-创建完成端口

2007-07-31 11:20 281 查看
l 创建完成端口
完成端口的原理是并发运行的线程必须有一个上限;也就是500个并行的客户端不允许500个线程同时存在。那么,仅仅是确切的并发运行的线程数目么?是的,如果仔细想想,就会意识到如果在一个双CPU的机器上有多于两个可运行的线程,而每个CPU对应于一个线程,并没有多大意义。一旦线程数量超过可用的CPU数量,系统就不得不花费时间进行线程切换,这将浪费CPU周期,这是并行模型的低效之处。

并行模型的另一个低效之处是为每个客户端请求创建新线程。相对于在本身的虚地址空间创建新进程来说,创建线程代价较低,但并不是免费的。如果在服务应用程序初始化的时候建立线程池将会提高性能,这些线程可以在程序内循环使用。I/O完成端口被设计成使用线程池来工作。

I/O完成端口可能是最复杂的内核对象。要创建I/O完成端口,需要调用CreateIoCompletionPort函数:


HANDLE CreateIoCompletionPort(
HANDLE hfile,
HANDLE hExistingCompPort,
ULONG_PTR CompKey,
DWORD dwNumberOfConcurrentThreads);


该函数执行两个不同的任务:创建I/O完成端口,将设备与I/O完成端口关联。这个函数相当复杂,在我看来,微软应该将其拆分为两个函数。当我使用I/O完成端口时,创建两个小函数来将CreateIoCompletionPort的两种能力分开。我创建第一个函数称为CreateNewCompletionPort,实现如下:


HANDLE CreateNewCompletionPort(DWORD dwNumberOfConcurrentThreads) {


return(CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0,
dwNumberOfConcurrentThreads));
}


该函数带有一个参数:dwNumberOfConcurrentThreads,内部调用CreateIoCompletionPort函数,将硬编码的值作为前三个参数,dwNumberOfCocurrentThreads作为最后一个。可以看到,CreateIoCompletionPort函数的前三个参数仅在将设备与完成端口关联时有用(很快会讲到)。为了创建完成端口,我将用INVALID_HANDLE_VALUE,NULL,0来对应CreateIoCompletionPort的前三个参数。

dwNumberOfConcurrentThreads参数告诉完成端口同时可运行线程的最大数量。如果该参数为0,完成端口默认与值与机器的CPU数相同。这对于避免额外的线程切换相当有用。如果客户端请求需要较长的运算,增加这个值会减少阻塞,但强烈建议不要增加这个值。可以尝试不同的值来体验一下应用程序的表现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐