在以前的文章中,我已经描述了使用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采用了后进先出的原则。例如当有A、B、C、D 4个等待线程队列,那么当数据投递过来以后IOCP会选择最后一次调用GetQueuedCompletionStatus的线程去处理这个数据。例如最后调用GetQueuedCompletionStatus的线程为A,那么线程A会被唤醒。同理当线程A正在处于繁忙状态时,则剩余的等待线程队列中的最后一个调用GetQueuedCompletionStatus函数的线程会被唤醒,去进行处理。
 
通过以上两点来看,使用IOCP来编写线程池对于开发服务端程序是非常有好处的。
那么我们怎样用IOCP来编写线程池呢?
首先我们来分析一下IOCP在网络通信过程中是如何实现的,这有助于我们用IOCP来编写线程池。
 
在网络通信中,当我们使用IOCP来接收数据的时候,我们首先需要投递一个WSARecv函数,用来通知系统我们已经投递了接收请求,当系统接收到数据以后,会自动填充重叠结构,并从函数GetQueuedCompletionStatus返回这个重叠结构和数据的长度。而且我们也可以使用函数
PostQueuedCompletionStatus来投递我们自己定义的消息。这一点在IOCP编写线程池的时候尤为重要。
下一篇将将如何实现IOCP线程池。

IOCP线程池的开发-(1)相关推荐

  1. IOCP线程池的开发-(2)

    下来我们看一下如何使用Delphi编写一个IOCP的线程池. 创建一个IOCP线程池,至少需要2个基本类. 首先:我们定义一个管理工作线程的线程池类(TTheadPool),这个类用来将接收到的数据转 ...

  2. C++强化之路之线程池开发整体框架(二)

    一.线程池开发框架 我所开发的线程池由以下几部分组成:  1.工作中的线程.也就是线程池中的线程,主要是执行分发来的task.  2.管理线程池的监督线程.这个线程的创建独立于线程池的创建,按照既定的 ...

  3. DirectX12(D3D12)基础教程(十六)——实现渲染线程池:3个内核同步对象实现渲染线程池/大规模线程池

    文章目录 1.前言 2.深入了解MsgWaitForMultipleObjects()函数fWaitAll参数为TRUE时的问题 3.内核同步对象:CPU线程屏障(CPU Barrier)基础知识 4 ...

  4. java new thread参数_java线程池01-ThreadPoolExecutor构造方法参数的使用规则

    为了更好的使用多线程,JDK提供了线程池供开发人员使用,目的在于减少线程的创建和销毁次数,以此达到线程的重复利用. 其中ThreadPoolExecutor是线程池中最核心的一个类,我们先简单看一下这 ...

  5. C#.Net使用线程池(ThreadPool)与专用线程(Thread)

    线程池(ThreadPool)使用起来很简单,但它有一些限制: 1. 线程池中所有线程都是后台线程,如果进程的所有前台线程都结束了,所有的后台线程就会停止.不能把入池的线程改为前台线 程. 2. 不能 ...

  6. 美团动态线程池实践思路,开源了

    大家好,今天我们来聊一个比较实用的话题,动态可监控的线程池实践,全新开源项目(DynamicTp)地址在文章末尾,欢迎交流学习. 写在前面 稍微有些Java编程经验的小伙伴都知道,Java的精髓在ju ...

  7. 动态可监控线程池,你还没用起来吗?

    「使用线程池 ThreadPoolExecutor 过程中你是否有以下痛点呢?」 1.代码中创建了一个 ThreadPoolExecutor,但是不知道那几个核心参数设置多少比较合适 2.凭经验设置参 ...

  8. 美团动态线程池实践思路已开源

    项目地址 gitee地址:gitee.com/yanhom/dyna- github地址:github.com/lyh200/dyna- 系列文章 动态线程池框架(DynamicTp),监控及源码解析 ...

  9. 今天我们来聊一个比较实用的话题,动态可监控的线程池实践,全新开源项目

    大家好,今天我们来聊一个比较实用的话题,动态可监控的线程池实践,全新开源项目(DynamicTp)地址在下方,欢迎star交流学习. 项目地址 gitee地址:gitee.com/yanhom/dyn ...

最新文章

  1. 【Android 返回堆栈管理】打印 Android 中当前运行的 Activity 任务栈信息 | Activity 任务栈信息分析 | Activity 在相同 Stack 中的不同 Task
  2. 台式计算机不用待机还是关机好,电脑应该选择“关机”还是“休眠”?不关机对电脑有损伤吗?...
  3. OAuth2.0在项目中的应用
  4. 使用管控策略,设定多账号组织全局访问边界
  5. Spring.Net---4、IoC/DI注入方式
  6. 浅显理解*nix下的守护进程机制及fork函数
  7. 获取css样式的方法
  8. 基础知识复习(一)——C语言位运算符详解
  9. Julia : DataFrame常见用法
  10. 吉林大学软件学院黄庆道《最优化算法》对偶单纯形使用大M法条件
  11. ios 模拟器沙盒_ios 模拟器沙盒的位置 | 学步园
  12. 夹角余弦 python_python 根据余弦定理计算两边的夹角
  13. Win系统如何取消f1打开浏览器
  14. 一个完整的项目管理流程包括什么?项目管理者必看
  15. 小学教师计算机模块报哪些,小学计算机教师个人工作总结
  16. 70块钱打造简单家庭NAS
  17. linux共享文件夹找不到
  18. Android 蓝牙 主从关系,【实用】蓝牙主从一体模块SPP+BLE测试流程(XY-MBD07A为例)...
  19. revit学习笔记-体量和场地
  20. wow(1) : UI插件_EUI[1]_配置分享

热门文章

  1. 怎样发布一个工程到自己的GitHub
  2. 结对编程项目---四则运算
  3. 【bzoj2330】 [SCOI2011]糖果
  4. 如何在JS中应用正则表达式
  5. 数据结构基础(16) --树与二叉树
  6. 数据中台VS业务中台、数据中台VS数据仓库,到底有什么区别?
  7. 包教包会,7段代码带你玩转Python条件语句
  8. linux内核源码目录分析
  9. 面试官问我:解释一下Dubbo服务暴露
  10. 送分题,ArrayList 的扩容机制了解吗?