首页 新闻 会员 周边 捐助

关于.net下socket完成端口的问题[clr异步处理机制]

0
悬赏园豆:100 [已解决问题] 解决于 2013-12-11 18:28

大家好,我想问下.net中的io线程池和window下io完成端口的io等待线程之间是什么关系?

我们知道windows下io完成端口的io等待线程的数目很少,一般设置成cpu个数。在这些线程里面处理io完成队列上的io完成包,每当有异步io完成了都会在io等待线程上拿包处理。这里的io等待线程在while(1)循环中调用GetQueuedCompletionStatus方法阻塞拿包,而且最后调用这个方法的线程最先拿包处理,以一种栈的方式后入先出的从io完成队列上拿包,从而最大程度避免线程切换。

第一个问题:

.net下面的异步io操作是对windows下iocp的封装,让我不明白的是.net下的io线程池默认线程数1000个,那么这个里面的io线程和在windows下的io等待线程有什么关系?看过了<<clr via c#>>里面说的貌似clr中的io线程池就是windows下的io等待线程。但是这个默认数1000是怎么回事呢?让我不解。

第二个问题:

还有如果io线程池就是windows下的io等待线程,那么如果拿到io完成包后的处理是一个比较耗时间的业务计算过程,打比方说要5秒,我们对这种耗时的处理是不是不应该放在io等待线程中呢,因为io等待线程数太少(如果此时并发访问的数量已经把io等待线程全部耗尽,但是业务计算都没完成,此时是不能处理新的io完成包的),是不是应该放到另外的工作线程中处理?比如将拿到的io完成包放入一个队列中,然后线程池从队列中拿包处理,这样的处理机制是不是更合理。

希望我描述清楚了我的两个问题,请童鞋们帮忙解答。

谢谢。新人初到。

pianowh的主页 pianowh | 初学一级 | 园豆:112
提问于:2013-12-11 15:19
< >
分享
最佳答案
1

没有说等待线程数目一定就是多少,可以修改。

AsyncCallback 中代码执行时间应该尽可能短,如果不能足够短,那么你应该将代码放到工作线程中去执行,比如 ThreadPool.QueueUserWorkItem.

收获园豆:100
Launcher | 高人七级 |园豆:45050 | 2013-12-11 17:04

 嗯,我看了许多文章包括一些国外的都是这样说的。

现在我的问题就是如果是这样的话干嘛微软把io线程池的默认数设置成1000,因为实际上是不需要这么多的。

所以我就是对这里有疑问,我想是不是这个io线程池中的线程并不是等待在io完成端口上的线程,有另外的专用线程在这里等待(也就是常说的cpu数目个数的线程),然后会在这样的专用线程中把io完成包的数据抛给io线程池处理,因为如果是这种逻辑的话默认数1000就可以理解了,而且不需要放到专用的工作线程处理了,因为io线程池已经提供了这个功能。这是我自己的推测,无法确定。

pianowh | 园豆:112 (初学一级) | 2013-12-11 17:36

@pianowh: 因为 AsyncCallback 的执行总是有延迟的,这个延迟是多少,也不确定,所以设置高一点,避免没有可用的线程用于回调。ThreadPool.GetMaxThreads 中的 completionPortThreads 就是用于等待 IO 的线程。

Launcher | 园豆:45050 (高人七级) | 2013-12-11 17:57

@Launcher: 明白了,我刚刚也想明白了。谢谢了

pianowh | 园豆:112 (初学一级) | 2013-12-11 18:25
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册