IOCP的线程池管理

来源:互联网 发布:中国地壳运动观测网络 编辑:程序博客网 时间:2024/06/05 03:17

一直很迷惑IOCP是怎么管理线程池的.还有就是GetQueuedCompletionStatus函数和线程池是什么关系,是GetQueuedCompletionStatus通过线程池的线程调用完成请求,还是先调用GetQueuedCompletionStatus得到请求在把请求交给线程池的线程完成的呢?

当你创建一个了IOCP,并指定了能并发运行的线程数目(CPU*2).当完成的I/O项进入队列时,IOCP就要唤醒等待的线程.不过,IOCP只唤醒指定的数目的线程.假设有4个I/O请求完成了,IOCP只唤醒2个线程,另两个线程将继续休眠.可能要问,如果IOCP只能允许唤醒指定数目的线程,那么为什么还要创建多余的线程.原因是:当IOCP唤醒一个线程时,它把线程的ID放在了同它相关联的第4个数据结构(释放线程队列表中).这使的IOCP能记住它唤醒了哪个线程并允许它监视这些线程的执行.如果释放一个线程,就会把这个线程的ID从释放队列移到暂停线程队列中.IOCP的目标是使在释放线程队列表中的线程数与它被创建时指定的并发线程数相同.如果一个释放线程因某种原因进入了等待状态,释放线程列表变小,IOCP就释放另一个等待的线程.如果一个暂停线程唤醒来,它就离开暂停线程列表,重新进入释放线程列表.释放列表中的线程数可能比允许的最大并发线程数要大.

例子:如果端口队列有3个完成的I/O请求,只有两个线程唤醒来处理.如果一个运行的线程调用了Sleep或其他任何使它不能运行的函数.IOCP检测到这一点,就立刻唤醒第3个线程.最终,第一个线程会再次运行.这使的运行的线程数目大于系统中的CPU数目.不过,IOCP会意识到这一点.在线程数目少于CPU数目之前,不会唤醒其他线程.当线程在次调用GetQueuedCompletionStatus时,数目会降下了.

 

当线程池中的一个线程调用GetQueuedCompletionStatus时,调用线程的ID就会被放入该等待线程队列中.这样,IOCP就知道哪个线程在等待完成I/O的请求.