【C# 线程】IOCP IO完成端口-Windows系统下常见的7种I/O模型
一、IOCP(I/O Completion Ports)简介
要实现异步通信,必须要用到一个很风骚的I/O数据结构 ,叫重叠结构“Overlapped”,Windows里所有的异步通信都是基于它的,完成端口也不例外。
Overlapped重叠结构 这里可以简单的将其理解为一个操作系统和用户之间的参数传递变量,属于“单IO数据”的一部分)
(这张图是个人自己的理解,这两张图结合起来看)
当我们创建一个I/O完成端口的时候,系统内核实际上会创建5个不同的数据结构。
I/O完成端口如何管理线程池
现在是讨论I/O完成端口为什么如此有用的时候了。首先,当我们创建I/O完成端口的时候,需要指定允许多少个线程并发运行(此时并没有创建线程池)。正如前面已经提到过,我们通常会将这个值设为主机的CPU数量。当已完成的I/O项被添加到队列中的时候,I/O完成端口想要唤醒正在等待的线程。但是,完成端口唤醒的线程数量最多不会超过我们指定的数量。因此,如果有4个I/O请求已完成,有4个线程正在等待GetQueuedCompletionStatus,那么I/O完成端口只会唤醒两个线程,而让其他两个线程继续睡眠。当每个线程处理完-一个已完成的I/O项时,会再次调用GetQueuedCompletionStatus. 这时系统发现队列中还有其他的项,于是会唤醒同一个线程来对剩余的项进行处理。
如果读者仔细考虑一 下,就应该注意到有些东西没有太大的意义。如果完成端口只允许同时唤醒指定数量的线程,那么为什么还要让更多的线程在线程池中等待呢?举个例子,假设我们正在一台有两个CPU的机器上运行,我们创建了一个I/O完成端口,并告诉它同时最多只能有两个线程来处理已完成的项。但我们在线程池中创建了4个线程(是CPU数量的两倍)。看起来似乎我们创建了两个多余的线程,它们永远都不会被唤醒来处理任何东西。
但I/O完成端口是非常智能的。当完成端口唤醒一个线程的时候,会将该线程的线程标识符保存在与完成端口相关联的第4个数据结构中,也就是已释放线程列表(released thread list)。这使得完成端口能够记住哪些线程已经被唤醒,并监视它们的执行情况。如果一个已释放的线程调用的任何函数将该线程切换到了等待状态,那么完成端口会检测到这一情况,此时它会更新内部的数据结构,将该线程的线程标识符从已释放线程列表中移除,并将其添加到已暂停线程列表(paused thread list)中(与I/O完成端口相关联的第5个也是最后一个数据结构)。
完成端口的目标是根据在创建完成端口时指定的并发线程的数量,将尽可能多的线程保持在已释放线程列表中。如果一个已释放线程由于任何原因而进入等待状态,那么已释放线程列表会缩减,完成端口就可以释放另一个正在等待的线程。如果一个 已暂停的线程被唤醒,那么它会离开已暂停线程列表并重新进入已释放线程列表。这意味着此时已释放线程列表中的线程数量将大于最大允许的并发线程数量。
让我们把这些总结一下。 假设我们在一 台有两个CPU的机器上运行。我们创建了一个同时最多只允许两个线程被唤醒的完成端口,还创建了4个线程来等待己完成的IO请求。如果3个已完成的IO请求被添加到端的队列中,只有两个线程会被唤醒来对请求进行处理,这降低了可运行线程的数量,并节省了上下文切换的时间。现在,如果一个可运行线程调用了Sleep,WaitForSingleObject,WaitForMultipleObjects,SignalObjectAndWait,一个异步 I/O调用或任何能够导致线程变成不可运行状态的函数, I/O 完成端口会检测到这一情况并立即唤醒第3个线程。完成端口的目标是使CPU保持在满负荷状态下工作。
最后,第一个线程将再次变成可运行状态。当发生这种情况的时候,可运行线程的数量将超过系统中CPU的数量。但是,完成端口仍然知道这一点, 在线程数量降到低于CPU数量之前,它是不会再唤醒任何线程的。I/O完成端口体系结构假定可运行线程的数量只会在很短一段时间内高于最大允许的线程数量,一旦线程进入下一次循环并调用GetQueuedCompletionStatus,可运行线程的数量就会迅速下降。这就解释了为什么线程池中的线程数量应该大于在完成端口中设置的并发线程数量。
IOCP 用来进行线程间通信
I/O完成端口是一项非常棒的技术,并不一定要用于设备I/O还可以用来进行线程间通信。I/O 完成端口有一个函数,名叫PostQueuedCompletionStatus:
IOCP(I/O Completion Port,I/O完成端口)是Windows操作系统中伸缩性最好的一种I/O模型。
I/O 完成端口是应用程序使用线程池处理异步 I/O 请求的一种机制。处理多个并发异步I/O请求时,使用 I/O 完成端口比在 I/O 请求时创建线程更快更高效。
二、IOCP的优势
I/O 完成端口可以充分利用 Windows 内核来进行 I/O 调度,相较于传统的 Winsock 模型,IOCP 在机制上有明显的优势。
相较于传统的Winsock模型,IOCP的优势主要体现在两方面:独特的异步I/O方式和优秀的线程调度机制。
独特的异步I/O方式
IOCP模型在异步通信方式的基础上,设计了一套能够充分利用Windows内核的I/O通信机制,主要过程为:① socket关联iocp,② 在socket上投递I/O请求,③ 事件完成返回完成通知封包,④ 工作线程在iocp上处理事件。
IOCP的这种工作模式:程序只需要把事件投递出去,事件交给操作系统完成后,工作线程在完成端口上轮询处理。该模式充分利用了异步模式高速率输入输出的优势,能够有效提高程序的工作效率。
优秀的线程调度机制
完成端口可以抽象为一个公共消息队列,当用户请求到达时,完成端口把这些请求加入其抽象出的公共消息队列。这一过程与多个工作线程轮询消息队列并从中取出消息加以处理是并发操作。这种方式很好地实现了异步通信和负载均衡,因为它使几个线程“公平地”处理多客户端的I/O,并且线程空闲时会被挂起,不会占用CPU周期。
IOCP模型充分利用Windows系统内核,可以实现仅用少量的几个线程来处理和多个client之间的所有通信,消除了无谓的线程上下文切换,最大限度的提高了网络通信的性能。
【C# 线程】IOCP IO完成端口-Windows系统下常见的7种I/O模型的更多相关文章
- 【C# 线程】Windows系统下常见的7种I/O模型 之Overlapped I/O模型
overview 这个字符到底是什么含义呢?其实它的意思就是当程序在等待设备操作的时候,可以继续往下做而不必阻塞到那个地方等待设备操作的返回,这就造成了程序运行和设备操作时间上的重叠. Overla ...
- windows系统下npm升级的正确姿势以及原理
本文来自网易云社区 作者:陈观喜 网上关于npm升级很多方法多种多样,但是在windows系统下不是每种方法都会正确升级.其中在windows系统下主要的升级方法有以下三种: 首先最暴力的方法删掉no ...
- windows系统下在dos命令行kill掉被占用的pid (转)
原文出自:http://www.2cto.com/os/201304/203771.html windows系统下在dos命令行kill掉被占用的pid 1.开始-->运行-->c ...
- windows系统下安装MySQL
可以运行在本地windows版本的MySQL数据库程 序自从3.21版以后已经可以从MySQL AB公司获得,而且 MYSQL每日的下载百分比非常大.这部分描述在windows上安装MySQL的过程. ...
- Windows系统下Memcached缓存系列二:CouchbaseClient(c#客户端)的详细试用,单例模式
在上一篇文章里面 ( Windows系统下Memcached缓存系列一:Couchbase(服务器端)和CouchbaseClient(c#客户端)的安装教程 ),我们介绍了服务器端的安装和客户端的安 ...
- Windows系统下Nginx的安装与配置
Nginx是lgor Sysoev在2004年的时候为俄罗斯访问量第二大的rambler.ru站点设计开发的,发布至今,凭借开源的力量,已经接近成熟与完善.其功能丰富,可作为HTTP服务器,也可作为反 ...
- Windows系统下的TCP参数优化(注册表\TCPIP\Parameters)
转自:https://blog.csdn.net/libaineu2004/article/details/49054261 Windows系统下的TCP参数优化 TCP连接的状态与关闭方式及其对 ...
- Tomcat Windows 系统下安装及注意事项
1 获取Tomcat 安装包 http://tomcat.apache.org/ tar.gz 文件是Linux系统下的安装版本 exe文件是 Windows系统下的安装版本 zip 文件是Wind ...
- Windows系统下安装zabbix客户端
简单介绍如何在windows系统下安装zabbix客户端 1. 首先下载和zabbix服务端大版本相同的windows客户端 例如我服务端安装的是zabbix-3.4.14.tar.gz ...
随机推荐
- 一些Markdown扩展语法
相信很多人跟我一样,对Markdown是"一知半解",会打一点,知道一点,但是其实从没花哪怕一分钟了解过.其实除了标题粗体插入代码,Markdown还有很多有趣的基础语法和扩展语法 ...
- 学习Java第5天
今天所做的工作: 1.包装类 2.数字处理类 3.ArrayList数组 4.学生信息管理系统样卷(部分) 明天工作安排: 1.完成学生信息管理系统样卷 2.核心技术接口继承,多态 所遇到的问题及解决 ...
- glibc-2.18升级
1.下载文件下载地址:https://mirrors.tuna.tsinghua.edu.cn/gnu/glibc/glibc-2.18.tar.gz 2.安装部署解压tar -zxvf glibc- ...
- TensorFlow 2.0 快速入门指南 | iBooker·ApacheCN
原文:TensorFlow 2.0 Quick Start Guide 协议:CC BY-NC-SA 4.0 自豪地采用谷歌翻译 不要担心自己的形象,只关心如何实现目标.--<原则>,生活 ...
- AT2043 [AGC004C] AND Grid
首先可以发现一个很简单的想法,因为最外层是一定不会有 \(\#\) 的,所以可以考虑让第一个网格图将每个连通块的最外层包起来,第二个网格图将就选择这个包内部的所有点即可. 但你发现这个想法是很难实现的 ...
- tcp 中 FLAGS字段,几个标识:SYN, FIN, ACK, PSH, RST, URG.
在TCP层,有个FLAGS字段,这个字段有以下几个标识:SYN, FIN, ACK, PSH, RST, URG. 其中,对于我们日常的分析有用的就是前面的五个字段.它们的含义是: 1.SYN表示建立 ...
- Android返回键
感谢大佬:https://www.cnblogs.com/qiluboy/p/5308310.html Android中back键和home键的区别: back键 Android的程序无需刻意的去退出 ...
- 一次线上服务高 CPU 占用优化实践 (转)
线上有一个非常繁忙的服务的 JVM 进程 CPU 经常跑到 100% 以上,下面写了一下排查的过程.通过阅读这篇文章你会了解到下面这些知识. Java 程序 CPU 占用高的排查思路 可能造成线上服务 ...
- UIView与核心动画对比?
1.UIView和核心动画区别? 核心动画只能添加到CALayer 核心动画一切都是假象,并不会改变真实的值. 2.什么时候使用UIView的动画? ...
- HTML页元素自适应+居中总结(不定期补充)
感谢大佬:https://www.cnblogs.com/SallyShan/p/11480685.html 图片自适应 背景图片自适应 /*背景页*/ #page_content{ width: 1 ...