IOCP线程池的开发-(1)

在以前的文章中,我已经描述了使用IOCP来编写一个可以支持大量数据连接的网络通信部分的内容。但是IOCP的作用仅限于用来编写网络通信吗?答案是否定的。在《windows核心编程》一书中,作者也说明了使用IO完成端口允许我们向一个设备同时发送多个IO请求,它允许一个线程发出IO请求,另一个线程对结果进行处理,这项技术具有高度的伸缩性和最佳的灵活性windows核心编程第297页)。这就说明了IOCP不只是用来开发网络代码,只要是IO的投递处理都可以用IOCP来处理。这样的话我们就可以使用IOCP来开发我们的线程池了。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

 

为什么非要用IOCP来开发线程池呢?让我们来分析一下线程池的作用,以及IOCP来开发线程池的好处。

 

当我们做服务端开发的时候,经常需要对一些慢设备进行操作(例如数据库,文件等等)。当我们只使用一个线程来处理慢设备的时候,会发现我们的程序运行起来CPU利用率过低,处理速度过慢。如果我们使用多线程同时来操作,就可以大大提高效率。但是我们自己写多线程调度的时候却存在2个难以处理的问题:

1 :我们需要开多少个线程合适?因为我们知道过多的线程在CPU调度切换的时候会有相当大的消耗,从而造成效率的低下(一些初学者理解的线程越多速度越快的观点是错误的)。

2 :我们如何调度线程?当我们操作多线程的时候我们如何选取合适的线程来处理呢?如果只用一个指定的线程那自然不行(这样的话和单线程没有任何区别了)。那我们又如何选择合适的线程呢?我想大家一定可以实现,但是实现的结果就是需要进行大量的判断,然后来选择合适的线程处理。这样本身增加了编码复杂度,而且降低了效率。(大道至简,这句话用在开发上简直是太精辟了)。

 

而这两个问题,IOCP却恰恰已经为我们解决了。

1 IOCP在一台机器上开的线程数量是有一定规定的。一般来说是CPU数量的*2 + 2。(有的书上说是*2)。

2 :对于线程的调度,IOCP采用了后进先出的原则。例如当有ABCD 4个等待线程队列,那么当数据投递过来以后IOCP会选择最后一次调用GetQueuedCompletionStatus的线程去处理这个数据。例如最后调用GetQueuedCompletionStatus的线程为A,那么线程A会被唤醒。同理当线程A正在处于繁忙状态时,则剩余的等待线程队列中的最后一个调用GetQueuedCompletionStatus函数的线程会被唤醒,去进行处理。

 

通过以上两点来看,使用IOCP来编写线程池对于开发服务端程序是非常有好处的。

 

那么我们怎样用IOCP来编写线程池呢?

首先我们来分析一下IOCP在网络通信过程中是如何实现的,这有助于我们用IOCP来编写线程池。

 

在网络通信中,当我们使用IOCP来接收数据的时候,我们首先需要投递一个WSARecv函数,用来通知系统我们已经投递了接收请求,当系统接收到数据以后,会自动填充重叠结构,并从函数GetQueuedCompletionStatus返回这个重叠结构和数据的长度。而且我们也可以使用函数

PostQueuedCompletionStatus 来投递我们自己定义的消息。这一点在IOCP编写线程池的时候尤为重要。

 

下一篇将将如何实现IOCP线程池

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值