同步處理和重迭的輸入和輸出

您可以在檔案、具名管道和序列通訊裝置上執行同步或非同步 (也稱為重迭) I/O 作業。 WriteFileReadFileDeviceIoControlWaitCommEventConnectNamedPipeTransactNamedPipe函式可以同步或非同步執行。 ReadFileExWriteFileEx函式只能以非同步方式執行。

當函式以同步方式執行時,它不會在作業完成之前傳回。 這表示呼叫執行緒的執行可能會無限期地遭到封鎖,同時等候耗時的作業完成。 針對重迭作業呼叫的函式可以立即傳回,即使作業尚未完成也一樣。 這可讓背景執行耗時的 I/O 作業,而呼叫執行緒可以自由執行其他工作。 例如,單一線程可以在不同的控制碼上執行同時 I/O 作業,或甚至是在相同的控制碼上同時讀取和寫入作業。

若要將其執行與重迭作業完成同步處理,呼叫執行緒會使用 GetOverlappedResult 函式、 GetOverlappedResultEx 函式,或其中一個 等候函 式來判斷重迭作業何時完成。 您也可以使用 HasOverlappedIoCompleted 宏來輪詢完成。

若要取消所有擱置的非同步 I/O 作業,請使用 CancelIoEx 函式,並提供 一個重迭 結構,以指定要取消的要求。 使用 CancelIo 函式,針對指定的檔案控制代碼,取消呼叫執行緒所發出的暫止非同步 I/O 作業。

重迭的作業需要使用 FILE_FLAG_OVERLAPPED 旗標建立的檔案、具名管道或通訊裝置。 當執行緒呼叫函式 (,例如 ReadFile 函式) 來執行重迭的作業時,呼叫執行緒必須指定 迭結構的指標。 (如果此指標為Null,則函式傳回值可能會不正確地指出作業已完成。) 除非事件用來表示 I/O 作業完成,否則必須初始化為零。 如果使用事件,重迭結構的hEvent成員會指定配置之事件物件的控制碼。 當呼叫 I/O 函式完成之前,系統會將事件物件的狀態設定為非簽署。 當作業完成時,系統會將事件物件的狀態設定為發出訊號。 只有在同時有一個以上的未完成 I/O 作業時,才需要事件。 如果未使用事件,則每個已完成的 I/O 作業都會向檔案、具名管道或通訊裝置發出訊號。

呼叫函式以執行重迭的作業時,可能會在函式傳回之前完成作業。 發生這種情況時,結果會以同步方式執行作業一樣處理。 不過,如果作業尚未完成,則函式的傳回值為 FALSE,而 GetLastError 函式會傳回 ERROR_IO_PENDING

執行緒可以透過下列兩種方法之一來管理重迭的作業:

  • 使用 GetOverlappedResultGetOverlappedResultEx 函式,等候重迭的作業完成。 如果使用 GetOverlappedResultEx ,則呼叫執行緒可以指定重迭作業的逾時,或執行可警示的等候。
  • 在其中一個等候函式中指定RESETED結構的手動重設事件物件的控制碼,然後在等候函式傳回之後,呼叫GetOverlappedResult 或 GetOverlappedResultEx 函式會傳回已完成重迭作業的結果,而針對適當資訊的函式,它會報告已傳輸的實際位元組數目。

在單一線程上執行多個同時重迭的作業時,呼叫執行緒必須為每個作業指定 迭結構。 每個 RESETED 結構都必須指定不同手動重設事件物件的控制碼。 為了等候任何一個重迭的作業完成,執行緒會將所有手動重設事件控制碼指定為多個物件 等候函式之一的等候準則。 多重物件等候函式的傳回值表示已發出手動重設事件物件的訊號,因此執行緒可以判斷哪個重迭的作業導致等候作業完成。

針對每個重迭的作業使用個別的事件物件比較安全,而不是指定任何事件物件,或針對多個作業重複使用相同的事件物件。 如果未在 OVERLAPPED 結構中指定任何事件物件,系統會在重迭作業完成時,發出檔案、具名管道或通訊裝置的狀態。 因此,您可以將這些控制碼指定為等候函式中的同步處理物件,但其用於此目的可能很困難,因為當在相同的檔案、具名管道或通訊裝置上執行同時重迭的作業時,沒有任何方法可以知道哪個作業導致物件的狀態收到訊號。

執行緒不應該重複使用事件,假設事件只會由該執行緒的重迭作業發出訊號。 事件會在與完成的重迭作業相同的執行緒上發出訊號。 在多個執行緒上使用同一個事件可能會導致事件正確發出訊號的競爭條件,而該執行緒的作業會先完成,並提前針對使用該事件的其他執行緒發出訊號。 然後,當下一個重迭的作業完成時,使用該事件的所有線程會再次發出事件訊號,直到所有重迭的作業都完成為止。

如需說明使用重迭作業、完成常式和 GetOverlappedResult 函式的範例,請參閱 使用管道

Windows Vista、Windows Server 2003 和 Windows XP:

重複使用 重迭 結構時請小心。 如果在多個執行緒上重複使用 OVERLAPPED 結構,而且 呼叫 GetOverlappedResult,會將 bWait 參數設定為 TRUE,則呼叫執行緒必須確定在重複使用結構之前會發出關聯的事件訊號。 呼叫GetOverlappedResult之後,可以使用WaitForSingleObject函式來強制執行緒等候作業完成。 請注意,事件物件必須是手動重設事件物件。 如果使用 autoreset 事件物件,呼叫 GetOverlappedResult 並將 bWait 參數設定為 TRUE ,就會無限期地封鎖函式。 此行為從 Windows 7 和 Windows Server 2008 R2 開始變更,適用于將 Windows 7 指定為應用程式資訊清單中支援的作業系統的應用程式。 如需詳細資訊,請參閱 應用程式資訊清單

I/O 概念