您目前已離線,請等候您的網際網路重新連線

不支援您的瀏覽器

您必須更新瀏覽器,才能使用此網站。

更新至最新版本的 Internet Explorer

非同步的磁碟 I/O 會在 Windows 上出現為同步

請注意--重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,且可能由 Microsoft Community 利用 Community Translation Framework技術或人工進行事後編修。翻譯過程並無專業譯者參與。Microsoft 同時提供使用者人為翻譯、機器翻譯及社群編修後的機器翻譯三種版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,所有翻譯文章都可能不盡完美,內容都可能出現詞彙、語意或文法上的錯誤。就翻譯內容之不正確或錯誤,或客戶因使用翻譯內容所產生的任何損害,微軟不負擔任何責任。Microsoft將依合理的商業努力不斷地更新機器翻譯軟體和工具,以期能為使用者提供更好的服務。

按一下這裡查看此文章的英文版本:156932
結論
在 Microsoft Windows 的檔案 I/O 可以是同步或非同步。其中的 I/O 函式呼叫,並傳回 I/O 完成時,I/O 的預設行為是同步的。非同步 I/O 允許 I/O 函式執行回呼叫端立即傳回,但 I/O 不會被視為一些時間才完成。I/O 完成時,作業系統會通知呼叫端。此外,呼叫端可以使用作業系統的服務以決定未完成 I/O 作業的狀態。

非同步 I/O 的優點是呼叫者必須進行其他工作,或發出多個要求,I/O 作業完成後的時間。詞彙重疊我/Ois 經常使用的非同步 I/O 與非重疊的 I/O 來同步 I/O。本文使用詞彙非同步和同步 I/O 作業。本文假設讀者已熟悉的檔案 I/O 函式,例如 createfile 而,ReadFile,WriteFile。

通常,非同步 I/O 作業的行為只為同步 I/O。 本文將告訴您在稍後的章節讓 I/O 作業完成同步特定條件。因為 I/O 函式不會傳回 I/O 完成之前,呼叫端具有背景工作沒有時間。

同步和非同步 I/O 相關幾個函式。本文使用 ReadFile 和 WriteFile 做為範例。很好的替代方案就是 ReadFileEx,WriteFileEx。本文將告訴您特別磁碟 I/O,雖然許多原則可以套用至其他類型的 I/O,序列 I/O 或網路 I/O 等。
其他相關資訊

設定非同步 I/O

在開啟檔案時,必須指定 FILE_FLAG_OVERLAPPED 旗標中 createfile 而。此旗標允許以非同步方式執行檔案 I/O 作業。以下是範例:
   HANDLE hFile;   hFile = CreateFile(szFileName,                      GENERIC_READ,                      0,                      NULL,                      OPEN_EXISTING,                      FILE_FLAG_NORMAL | FILE_FLAG_OVERLAPPED,                      NULL);   if (hFile == INVALID_HANDLE_VALUE)      ErrorOpeningFile();				
請小心編碼非同步 I/O,因為系統會保留 theright 進行作業,需要同步時。因此,最好是如果您撰寫程式,正確地處理可能在同步或非同步完成的 I/O 操作。在 [程式碼範例示範這項考量。

有許多事情,程式可以執行時若要完成,如佇列的其他作業或 doingbackground 工作正在等候 asynchronousoperations。例如,下列程式碼正確 handlesoverlapped 和非重疊的讀取作業的完成。它 doesnothing 超過等待未完成的 I/O 完成:
   if (!ReadFile(hFile,                 pDataBuf,                 dwSizeOfBuffer,                 &NumberOfBytesRead,                 &osReadOperation )   {      if (GetLastError() != ERROR_IO_PENDING)      {         // Some other error occurred while reading the file.         ErrorReadingFile();         ExitProcess(0);      }      else         // Operation has been queued and         // will complete in the future.         fOverlapped = TRUE;   }   else      // Operation has completed immediately.      fOverlapped = FALSE;   if (fOverlapped)   {      // Wait for the operation to complete before continuing.      // You could do some background work if you wanted to.      if (GetOverlappedResult( hFile,                               &osReadOperation,                               &NumberOfBytesTransferred,                               TRUE))         ReadHasCompleted(NumberOfBytesTransferred);      else         // Operation has completed, but it failed.         ErrorReadingFile();   }   else      ReadHasCompleted(NumberOfBytesRead);				
請注意,& NumberOfBytesRead 傳入 ReadFile 是不同的 & NumberOfBytesTransferred 傳遞至 GetOverlappedResult。如果作業已進行非同步的則 GetOverlappedResult 會使用 determinethe 後作業中所傳輸的位元組數實際 hascompleted。& NumberOfBytesRead 傳入 ReadFile 是無意義。

如果相反地,會立即完成作業,然後 & NumberOfBytesRead 傳入 ReadFile 是有效的讀取的位元組數目。在此情況下,略過傳遞至 ReadFile ; OVERLAPPED 結構不要使用它與 GetOverlappedResult 或 WaitForSingleObject。

與非同步作業的另一個要注意的是您必須使用 OVERLAPPED 結構,直到其暫止的作業已經完成。在 otherwords,如果您有三個未完成 I/O 作業,您必須使用三個 OVERLAPPED 結構。如果您重複使用的 OVERLAPPED 結構,您會收到無法預期的結果在 I/O 作業中,您可能會遇到資料損毀。此外,您可以使用 OVERLAPPED 結構第一次,或之前您重複使用先前的作業完成後,您必須正確地將它初始化,沒有左移轉資料會影響新的作業。

相同類型的限制會套用到 anoperation 中所使用的資料緩衝區。將資料緩衝區未被讀取或寫入之前 itscorresponding I/O 作業完成為止。讀取或寫入 buffermay 會導致錯誤與損毀的資料。

非同步 I/O 仍然顯示為同步

如果您依照本文先前的指示,不過,您所有的 I/O 作業仍然通常完成同步發行、 順序和無 ReadFile 作業會傳回 FALSE GetLastError() 傳回 ERROR_IO_PENDING,這表示您有任何背景工作沒有時間。為什麼這發生?

有許多原因會 I/O 作業完成 synchronouslyeven,如果您有程式碼取得非同步作業的原因:

壓縮

非同步作業的一個障礙是 NTFS 壓縮。檔案系統驅動程式將不會以非同步的方式 ; 壓縮的檔案存取而是 alloperations 只會進行同步。這並不適用於檔案與公用程式類似壓縮或 PKZIP 的 arecompressed。

NTFS 加密

類似於壓縮,檔案加密會導致系統驅動程式,將轉換為同步的非同步 I/O。如果檔案都解密,將會非同步 I/O 要求。

延伸檔案

已同步完成 I/O 作業的另一個原因是本身的作業。在 Windows NT 上任何寫入作業以延伸其長度的檔案會同步。

附註: 應用程式可以使先前所述的寫入操作非同步藉由使用 SetFileValidData 函式,然後發行 WriteFile 變更檔案的有效資料長度。

使用 SetFileValidData (這是可以在 Windows XP 和更新版本),應用程式可以有效率地擴充檔而不會為零填入它們對效能產生負面影響。

因為 NTFS 檔案系統不為零的填滿資料由 SetFileValidData 所定義的有效資料長度 (VDL),這個函式可以具有安全性含意檔案可能被指派的先前佔據的其他檔案的叢集。因此,SetFileValidData 需要呼叫端具有新啟用的 SeManageVolumePrivilege (根據預設,這指派只給系統管理員)。Microsoft 建議 Isv 仔細考慮使用這個函式的含意。

快取

大多數的 I/O 驅動程式 (磁碟、 通訊、 和其他人) 有特殊案例程式碼,如果可以在 「 立即 」 完成 I/O 要求,將會完成該操作,在 ReadFile 或 WriteFile 函數會傳回 TRUE。所有的方式,這些類型的操作看起來似乎同步。為 diskdevice,一般而言,I/O 要求可以完成在記憶體中快取的資料時,「 立即 」。

資料不在快取

快取配置可以運作,不過,如果資料不是 thecache。Windows NT 快取是在內部使用檔案對應來實作的。記憶體管理員在 Windows NT 並不會提供一個非同步的分頁錯誤的機制來管理快取管理員所使用的檔案對應。Thecache 管理員可以,不過,會確認要求的網頁是否在記憶體中,因此如果您發出非同步的快取的讀取,而且網頁不在記憶體中,檔案系統驅動程式會假設不想讓您封鎖的執行緒,並將由有限的集區的工作者執行緒處理要求。程式控制權回到您的程式之後您 ReadFile 使用呼叫仍在擱置中讀取。

這可以適用於少量的要求,但因為背景工作執行緒集區是那里限制 (目前三個 16 MB 的系統上),會仍然只有幾個要求排入磁碟驅動程式特定的時間。如果發出大量 I/O 作業,不是快取中的資料時,快取管理員和記憶體管理員會變得飽和,您的要求會進行同步。

快取管理員的行為也受影響根據 whetheryou 存取檔案循序或隨機。依序存取檔案時,快取的優點是 seenmost。FILE_FLAG_SEQUENTIAL_SCAN flagin createfile 而呼叫會最佳化這種類型的存取快取。不過,如果您存取以隨機方式的檔案,請使用 theFILE_FLAG_RANDOM_ACCESS 旗標 createfile 而以指示快取管理員 tooptimize 隨機存取其行為。

不使用快取

FILE_FLAG_NO_BUFFERING 旗標的效果大部分的非同步作業的 thefile 系統行為。這是的 guaranteethat I/O 要求會實際非同步的最佳方式。它會指示檔案 systemto 不使用任何快取機制根本。

警告: 有一些限制使用這個旗標,則是要使用的資料緩衝區對齊方式和裝置的磁區大小。請參閱 createfile 而函式,如需有關適當地使用這個旗標的文件中的函式參考。

真實世界的測試結果

以下是一些的測試結果的範例程式碼。Thenumbers 的大小並不重要,這裡和不同電腦,但數字的關係互相比較光線照亮 thegeneral 影響效能的旗標。

您可以預期看到類似下列的結果:
  • 測試 1
    Asynchronous, unbuffered I/O:  asynchio /f*.dat /n   Operations completed out of the order in which they were requested.   500 requests queued in 0.224264 seconds.   500 requests completed in 4.982481 seconds.						
    這項測試會示範先前所述的程式快速發出 500 的 I/O 要求,並且有很多時間來執行其他工作或發出多個要求。
  • 測試 2
    Synchronous, unbuffered I/O: asynchio /f*.dat /s /n   Operations completed in the order issued.   500 requests queued and completed in 4.495806 seconds.						
    這項測試會示範這個程式所花費的 4.495880 呼叫 ReadFile 完成其作業,而測試 1 花費只 0.224264 秒發出相同要求的秒數。在測試 2,沒有 「 額外 」 的時間來進行任何背景工作的程式。
  • 測試 3
    Asynchronous, buffered I/O: asynchio /f*.dat   Operations completed in the order issued.   500 requests issued and completed in 0.251670 seconds.						
    這項測試會示範快取同步性質。所有的讀取已發出,並且在 0.251670 秒內完成。換言之,非同步要求已完成同步。這項測試也會示範快取管理員高效能資料時快取中。
  • 測試 4
    Synchronous, buffered I/O: asynchio /f*.dat /s   Operations completed in the order issued.   500 requests and completed in 0.217011 seconds.						
    這項測試會示範測試 3 相同的結果。請注意從快取同步讀取快一點比非同步讀取完成從快取。這項測試也會示範快取管理員高效能資料時快取中。

結論

您可以決定哪一種方法最好,因為它所有相依於型別、 大小和您的程式執行的作業數目。

預設檔案而不需要指定任何特殊的旗標,以 CreateFileis 同步和快取作業存取。

附註: 您不要在此模式中取得一些自動的非同步行為,因為檔案系統驅動程式做了預測非同步先期讀取和非同步延遲寫入已修改的資料。雖然這不會讓應用程式的 I/O 非同步,它會是絕大多數的簡單應用程式的理想情況。

如果相反地,您的應用程式並不簡單,您可能必須 dosome 程式碼剖析和效能監視來決定最好的方法,類似於本文稍早介紹的測試。程式碼剖析時間花在 theReadFile 或 WriteFile 函式,然後比較如何這次長它 takesfor 實際 I/O 作業的完成是相當有用。如果在實際發出 I/O,則您 I/O 所花費的時間是 majorityof beingcompleted 同步。不過,如果所花費的時間發行 I/O 要求 isrelatively 小相較於它所需的時間的 I/O 作業 tocomplete,然後正在非同步處理您的作業。本文稍早所述的 samplecode 會使用 QueryPerformanceCounter 函式來執行其 owninternal 程式碼剖析。

效能監視可以協助您判斷如何有效率地程式 isusing 磁碟和快取。追蹤任何快取物件的效能計數器會指出快取管理員的效能。實體磁碟或邏輯的 Diskobjects 追蹤的效能計數器會指出磁碟系統的效能。

有幾個公用程式很有幫助效能監視。效能監視器與 DiskPerf 會特別有用。要讓系統收集資料,在 [磁碟系統的效能,您必須先發行 diskperf-y 命令。發出命令之後,您必須重新啟動資料收集系統。
参考
請參考上的 MSDN 文件 同步和非同步 I/O 如需詳細資訊。

Asynczip ReadFile ReadFileEx WriteFile kbdss WriteFileEx GetOverlappedResult 非同步同步重疊的非重疊的 kbfile

警告:本文為自動翻譯

內容

文章識別碼:156932 - 最後檢閱時間:06/27/2015 02:25:00 - 修訂: 7.0

  • Microsoft Win32 Application Programming Interface
  • kbapi kbfileio kbinfo kbkernbase kbmt KB156932 KbMtzh
意見反應
t type="text/javascript" src="https://c.microsoft.com/ms.js">