如何为具有可能执行阻塞操作的连接的IOCP服务器设置线程池

时间:2015-09-30 04:24:06

标签: windows threadpool iocp

我正在研究一个以proactor风格编写的服务器应用程序,使用select()+动态大小的线程池(基于跟踪空闲工作线程的简单机制)。

我需要修改它以在Windows上使用IOCP而不是select(),我想知道利用线程的最佳方法是什么。

对于背景信息,服务器具有有状态的长期连接,并且任何请求都可能需要大量处理和阻止。事实上,大多数请求都会调用客户编写的代码,这些代码可能会随意阻止。

我已经读过操作系统可以告诉IOCP线程何时阻塞,并解除阻止另一个线程,但看起来不支持在高负载下创建其他线程,或者许多线程被阻塞。

我读过一个网站,它建议你有一个小的,固定大小的线程池,它使用IOCP来处理I / O,它发送的请求可以阻塞到另一个动态大小的线程池。由于需要额外的线程同步(尽管您可以将IOCP用于第二个线程池的任务),并且需要更多的线程(额外的上下文切换),这似乎不是最佳的。

这是最好的方法吗?

1 个答案:

答案 0 :(得分:1)

听起来你读过的是关于IOCP的一篇文章(最有可能this one)。现在可能有点过时,因为它排除了整个问题(如果在I / O完成之前发出它的线程退出,I / O被取消)不再是微软当前支持的任何问题操作系统(这只是XP和之前的问题)。

从上下文切换的角度来看,我注意到2000/2002年的设计是次优的是正确的。但鉴于底层API的限制,它在当时运作良好。

在现代操作系统上,为I / O和阻塞工作提供单独的线程池没有任何优势。更现代的解决方案可能涉及根据需要动态扩展和减少为IOCP服务的I / O线程数。

您需要跟踪活动的IOCP线程数(即不等待GetQueuedCompletionStatus())并在“太少”时生成更多。同样正如线程即将返回并等待GQCS一样,您可以检查是否有“太多”,如果是,请让它死掉。

我应该更新这些文章。