Windows的同步I/O和异步I/O
同步I/O操作
执行步骤
1. 程序通过FileStream对象来打开磁盘文件,然后调用Read方法(内部调用Win32 ReadFile函数),从文件中读取数据。这时,线程从托管代码转变为本机/用户模式代码。
2. Win32 ReadFile函数生成一个I/O请求包(IRP),并传递给Windows内核。
3. Windows内核将IRP传送给I/O硬件设备驱动程序的IRP队列。
4. 硬件设备执行I/O操作。在此期间,发出I/O请求的线程将变成睡眠状态。这样可以避免浪费CPU时间,但依然会浪费内存空间。因为线程的用户模式栈、内核模式栈、线程环境块和其他数据结构仍在内存中,而且无人访问。
5. 在硬件设备完成I/O操作后,线程被唤醒,从内核模式返回用户模式,再返回托管代码。
性能分析
1. 当客户端发起一个I/O请求时,线程池会创建一个线程,发起I/O请求后,线程会阻塞并等待响应。当客户端有多个I/O请求时,线程池不得不创建多个线程,这些线程都会阻塞。
2. 当I/O响应请求时,多个线程被解锁,开始执行。这时,由于CPU内核数量限制,CPU被迫执行频繁的上下文切换,这进一步损害了性能。
异步I/O操作
概述
异步执行的I/O限制的操作,允许将任务交由硬件设备处理,期间不占用线程和CPU资源。
各种I/O操作的结果由线程池来处理,因此线程池仍然扮演重要的角色。
执行步骤
1. 程序通过FileStream对象来打开磁盘文件,然后调用ReadAsync方法(内部调用Win32 ReadFile函数),从文件中读取数据。这时,线程从托管代码转变为本机/用户模式代码。
2. Win32 ReadFile函数生成一个I/O请求包(IRP),并传递给Windows内核。
3. Windows内核将IRP传送给I/O硬件设备驱动程序的IRP队列。
4. 线程立即从内核模式返回用户模式,再返回托管代码。这时FileStream的ReadAsync方法返回一个Task<Int32>对象。
5. 硬件设备执行I/O操作。
6. 在硬件设备完成I/O操作后,将完成的IRP放到线程池队列中。
7. 将来某个时间,一个线程池线程会提取完成的IRP,并访问读取到的数据。
性能分析
1. 在硬件设备执行I/O操作期间,线程不阻塞,可以避免线程池创建更多的线程。
2. 硬件设备执行I/O操作后,它的响应也会进入线程池队列,由线程池分配线程进行处理,可以更合理地利用线程,避免CPU的频繁上下文切换。
3. 异步I/O将线程控制在少数几个,可以节省内存空间,减少每次垃圾回收的时间,增强调试性能。
4. 异步I/O可以并发执行,减少处理时间。
Windows的同步I/O和异步I/O的更多相关文章
- 《Windows核心编程系列》十谈谈同步设备IO与异步设备IO之异步IO
同步设备IO与异步设备IO之异步IO介绍 设备IO与cpu速度甚至是内存访问相比较都是比较慢的,而且更不可预测.虽然如此,通过使用异步设备IO我们仍然能够创造出更高效的程序. 同步IO时,发出IO请求 ...
- Windows核心编程:第10章 同步设备IO与异步设备IO
Github https://github.com/gongluck/Windows-Core-Program.git //第10章 同步设备IO与异步设备IO.cpp: 定义应用程序的入口点. // ...
- Windows Phone 同步方式获取网络类型
原文:Windows Phone 同步方式获取网络类型 在Windows Phone 开发中有时候需要获取设备当前连接网络的类型,是Wifi,还是2G,3G,或者4G,SDK中提供获取网络类型的API ...
- 烂泥:Linux系统与windows系统文件同步
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 上篇文章中,我们介绍了有关Linux系统之间的文件同步,这篇文章我们来介绍下,有关Linux系统与windows系统,以及windows系统与windo ...
- windows线程同步
一.前言 之前在项目中,由于需要使用到多线程,多线程能够提高执行的效率,同时也带来线程同步的问题,故特此总结如下. 二.windows线程同步机制 windows线程同步机制常用的有几种:Event. ...
- 总结windows多线程同步互斥
windows多线程同步互斥--总结 我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同 ...
- 同步I/O、异步I/O与阻塞I/O、非阻塞I/O的区别
一.I/O I/O (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作. 通常用户进程中的一个完整I/O分为两阶段:用户进程空间<-->内核空间.内核空间< ...
- windows多线程同步互斥--总结
我的windows多线程系列文章: windows多线程--原子操作 windows多线程同步--事件 windows多线程同步--互斥量 windows多线程同步--临界区 windows多线程同步 ...
- windows多线程同步--临界区
推荐参考博客:秒杀多线程第五篇 经典线程同步 关键段CS 关于临界区的观念,一般操作系统书上面都有. 适用范围:它只能同步一个进程中的线程,不能跨进程同步.一般用它来做单个进程内的代码快同步,效率 ...
随机推荐
- C++——友元、异常和其他
一.友元 类并非只能拥有友元函数,也可以将类作为友元.在这种情况下,友元类的所有方法都可以访问原始类的私有成员和保护成员.另外,也可以做更严格的限制,只将特定的成员函数指定为另一个类的友元.哪些函数. ...
- android studio导入 so ,jar 文件。
环境为: Android Studio 1.0.2 如果是jar文件的话,请直接拷贝jar文件到项目的libs文件夹下,然后运行:Sync Project with Gradle Files.如下图2 ...
- openfire消息通知推送
package cn.zsmy.utils.openfire; import java.io.BufferedReader; import java.io.InputStreamReader; imp ...
- mybatis动态sql中foreach标签的使用
foreach标签主要用于构建in条件,他可以在sql中对集合进行迭代.如下: <delete id="deleteBatch"> delete from user w ...
- OpenGL的几何变换[转]
OpenGL的几何变换 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: ...
- Css_2跟3
#css2中的选择器 1.元素选择器 *通配符选择符.html类型选择符.id选择符.class选择符 2.关系选择器 E F(包含选择器).E>F(子选择器).E+F(E元素后 ...
- hiho_1062_最近公共祖先
题目大意 给出一棵家谱树,树中的节点都有一个名字,保证每个名字都是唯一的,然后进行若干次查询,找出两个名字的最近公共祖先. 分析 数据量较小,对于每次查询都进行如下操作: 先找出person1到达根节 ...
- easyui-datebox 只显示年月
$(function () { $('#niandu').datebox({ onShowPanel: function () {//显示日趋选择对象后再触发弹出月份层的事件,初始化时没有生成月份层 ...
- sqlserver计算表使用大小sql
) create table #spt_space ( ) null, [rows] int null, ) null, ) null, ) null, ) null ) set nocount on ...
- 数据库中间件mycat简单入门
当在项目中mysql数据库成为瓶颈的时候,我们一般会使用主从复制,分库分表的方式来提高数据库的响应速度,比如mysql主从复制,在没有数据库中间件的情况下,我们只能由开发工程师在程序中控制,这对于一个 ...