码迷,mamicode.com
首页 > 其他好文 > 详细

同步I/O操作和异步I/O操作

时间:2014-07-10 17:52:44      阅读:664      评论:0      收藏:0      [点我收藏+]

标签:同步   c#   异步   

当执行I/O操作的时候,无论是同步I/O操作还是异步I/O操作,都会调用的Windows的API方法,比如,当读取文件的时候,调用ReadFile函数。该方法会将你的当前线程从用户态转变成内核态,会生成一个I/O请求包,并且初始化这个请求包,这个包中包含一个文件句柄,一个偏移量和一个Byte[]数组。ReadFile会向内核传递,根据这个请求包,windows内核知道需要将这个I/O操作发送给哪个硬件设备。这些I/O操作会进入设备自己的处理队列中,该队列由这个设备的驱动程序维护。

如果此时是同步I/O操作,那么在硬件设备操作I/O的时候,发出I/O请求的线程由于无事可做被windows变成睡眠状态,当硬件设备完成操作后,再唤醒这个线程。这种方式非常直接,但是性能不高,如果请求数很多,那么休眠的线程数也很多,浪费了大量资源。

如果是异步I/O操作,那么情况不同了。.Net中,异步的I/O操作为BeginXXX的形式。该方法在Windows把I/O请求包发送到设备的处理队列后就返回了。同时,在调用异步I/O操作的时候,即调用BeginXXX方法的时候,需要传入一个委托,该委托方法会随着I/O请求包一路传递到设备的驱动程序。在设备处理完I/O请求包后,将该委托再放到CLR线程池队列。在CLR内部有一个IOCP(I/O completion port),它提供了在处理多个异步I/O请求的线程模型,可以把这个IOCP看做是一个消息队列,当一个进程创建了一个IOCP,即创建了一个队列。当异步I / O请求完成时,设备驱动程序就会生成一个I/O完成包,将它按照FIFO方式排队列入该完成端口。之后,会有线程提取完成I/O请求包,并调用之前的委托。IOCP会预分配的线程池,线程数量和CPU数量一致,这样的好处是避免了线程的上下文切换。这种方式比即时创建线程处理I/O请求速度更快。这种机制很好的实现了异步通信,既提高了性能又平衡了资源。

 

参考资料

《CLR VIA C#》

《Pro .NET Performance》

《Windows核心编程(第5版)中文版》

http://blog.csdn.net/piggyxp/article/details/6922277

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198(v=vs.85).aspx


本文出自 “一只博客” 博客,请务必保留此出处http://cnn237111.blog.51cto.com/2359144/1436502

同步I/O操作和异步I/O操作,布布扣,bubuko.com

同步I/O操作和异步I/O操作

标签:同步   c#   异步   

原文地址:http://cnn237111.blog.51cto.com/2359144/1436502

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!