我在我的應用程序中使用本機NT API來訪問文件(NtCreateFile/etc)。爲了避免處理STATUS_PENDING,我在打開相關文件時使用FILE_SYNCHRONOUS_IO_NONALERT標誌。因此,打開文件如下所示:如何正確等待NtCreateFile/etc的完成?
UNICODE_STRING fname = toNtUnicode(ntpath);
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &fname, 0, at.handle(), NULL);
HANDLE h;
IO_STATUS_BLOCK io_status;
NTSTATUS r = NtOpenFile(&h, GENERIC_READ|SYNCHRONIZE, &oa, &io_status,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT|FILE_DIRECTORY_FILE);
if (r != STATUS_SUCCESS)
...; // error handling
不幸的是,它導致內核序列化給定句柄上的所有操作。即如果我嘗試並行執行多個讀取(使用多個線程) - 只有一個請求將在任何時間點處理。
我能擺脫系列化:
HANDLE h;
IO_STATUS_BLOCK io_status;
NTSTATUS r = NtOpenFile(&h, GENERIC_READ|SYNCHRONIZE, &oa, &io_status,
FILE_SHARE_READ, FILE_DIRECTORY_FILE);
if (r == STATUS_PENDING)
...; // what to do here???
,但究竟如何,我應該等待完成 - WaitForSingleObject()
對文件處理?據我所知,由於許多原因它可以改變爲信號狀態 - 是否有任何方法可以告訴我打開的文件(或dir)操作已完成?同樣,如果我提交多個讀取(來自多個線程) - 我怎麼知道哪一個(如果有的話)完成了?
奇怪......我發誓,我觀察到STATUS_UPDATE時打開目錄。我會再試一次。同時,關於其他操作 - 我是否應該等待該事件傳遞給NtReadFile?如果是,那麼我並不需要SYNCHRONIZE標誌,對吧? –
NtClose()怎麼樣 - 它保證是同步的嗎?另外,我是否可以假定所有關於NtXXX函數的說法都同樣適用於相應的ZwXXX函數(如果在用戶模式下調用)? –
@ C.M。 'ZwOpenFile'和'ZwClose'是**同步** api的設計。它**從不**返回'STATUS_PENDING'。 * Nt *和* Zw *函數 - 在用戶模式下是別名。這是相同的功能(兩個名稱指向相同的地址) – RbMm