如何在windows中非同步打開文件
有沒有辦法在 Windows 中非同步打開文件?CreateFile API 函式只有 FILE_FLAG_OVERLAPPED 允許進一步的非同步讀寫。儘管如此,文件的打開似乎是同步的。鑑於它必須訪問文件系統(並可能執行昂貴的 IO 操作),它可能是一個潛在的阻塞器。
這實際上是一個潛在的問題,是否可以在 .NET 中非同步打開文件(因為不能等待 FileStream ctor)。但是,如果在作業系統中沒有辦法做到這一點,那麼這個問題就毫無意義了。
不幸的是,在使用者模式下無法非同步創建/打開文件。即使驅動程序返回
STATUS_PENDINGforIRP_MJ_CREATE,在這種情況下,系統將等待驅動程序完成,IRP然後再從創建/打開文件函式之一返回控制權。只有當我們處於核心模式時才有可能,如果您自己格式化
IRP_MJ_CREATE並將其發送給驅動程序。但即使在這種情況下,驅動程序幾乎總是會IRP_MJ_CREATE同步處理。對於 API 是非同步的 - 必須以某種方式在操作完成時通知呼叫者
windows為此使用了3種方法
- 參數中的一些回調常式,通常是
PIO_APC_ROUTINE操作完成時呼叫的 APC ( )- 參數中的一些事件,當操作完成時,事件設置為信號狀態。
- 在 api 呼叫中使用的文件句柄是為某些 IOCP 綁定的。當操作完成數據包排隊到 IOCP。(我們稍後通過呼叫
GetQueuedCompletionStatus(ZwRemoveIoCompletion)刪除此數據包或KeRemoveQueue
- 在我們的例子中是不可能的,因為文件句柄還沒有創建,所以它不能綁定到任何 IOCP。關於 1) 和 2) 讓我們查找文件打開/創建 api 簽名:
在使用者模式下,用於打開/創建文件的最低級別 api 是
ZwOpenFile和ZwCreateFile.CreateFile是殼結束ZwCreateFile。在核心模式NtOpenFile->NtCreateFile->IoCreateFile->IoCreateFileEx甚至 -IoCreateFileEx(創建文件的最低級別 api) - 沒有事件或$$ Apc $$回調參數 - 所以不是非同步的。
IoCreateFileEx呼叫ObOpenObjectByName(未記錄,但導出的常式) - 這裡也沒有 1)或 2)參數 - 這也是設計 api 同步的