1、簡介
關於Windows的異步I/O操作,只要解決的是同步I/O操作的線程利用率問題,通過異步I/O Api來提升線程的利用率,提升系統的吞吐能力,將各種I/O操作交給線程池然后交由硬件設備執行,期間完全不占用線程和CPU資源.
2、同步I/O存在的問題
當編寫同步I/O操作時,在硬件設備執行I/O操作的期間,當前線程會等待硬件設備完成執行,所以這個時候主線程處於休眠狀態(Windows控制),為了防止主線程浪費CPU時間,但是雖然不浪費時間,它還是會浪費內存!
static string _filePath = @"C:\Users\zhengchao\Desktop\測試文件.txt"; static void Main(string[] args) { //打開目標文件,並進行只讀操作(FileAccess.Read文件的操作權限) using (var stream = new FileStream(_filePath,FileMode.Open,FileAccess.Read)) { //打開磁盤文件后,先申明一個和流大小一樣的字節數組 var contentBytes = new byte[stream.Length]; //調用Read方法,當前主線程的托管代碼轉換為用戶模式代碼,接着Read會調用Win32 ReadFile函數 //ReadFile分配一個小的數據結構,即I/O請求包(I/O Request Packet,IRP),IRP結構包含如下內容 //文件句柄(關於文件句柄,可以在FileStream種給定IntPtr對象實例) //文件的偏移量(即你想從那個位置開始讀取文件,可在Read方法種給定offset參數) //一個Byte數組的地址,即給定Read方法成功讀取內容后,需要將內容填充至哪里 //此時當前主線的托管代碼已經轉換為用戶模式代碼,開啟向內核傳遞IRP數據,根據IRP種的設備句柄,Windows //知道要將I/O請求傳遞給哪個硬件設備,因此,Windows知道將IRP傳送給對應的設備驅動程序的IRP隊列,每個 //設備驅動程序都維護者自己的IRP隊列,其中運行者設備上所有進程發出的I/O請求,接着設備驅動程序會將IRP信息 //發送給物理設備上安裝的電路板,開始執行對應的I/O操作 //但是,在電路板執行I/O操作的期間,當前線程會等待電路板完成執行,所以這個時候主線程處於休眠狀態(Windows控制) //為了防止主線程浪費CPU時間,但是雖然不浪費時間,它還是會浪費內存! //最后,硬件設備完成I/O操作,Windows會喚起主線程,這個時候內核代碼會轉變成為托管代碼,最后Read方法會拿到 //一個int32值,該值說明從文件種讀取的實際字節數,使你知道在傳給Read的byte[]參數時,實際能傳遞什么值 var readResult=stream.Read(contentBytes, 0,contentBytes.Length); Console.WriteLine(contentBytes.ConvertToString()); } Console.ReadKey(); } } public static class ByteExtension { public static string ConvertToString(this byte[] bytes) { return Encoding.Default.GetString(bytes); } }
關於Windows如何執行同步I/O操作的過程,代碼種都由說明,但是明顯同步的方式,CPU利用率很低.