同步和重迭管道 I/O
ReadFile、WriteFile、TransactNamedPipe和 ConnectNamedPipe 函式可以在管道上同步或異步執行輸入和輸出作業。 當函式以同步方式執行時,它不會傳回,直到它正在執行的作業完成為止。 這表示呼叫線程的執行可以無限期地封鎖,同時等候耗時的作業完成。 當函式以異步方式執行時,它會立即傳回,即使作業尚未完成也一樣。 這可讓背景執行耗時的作業,同時呼叫線程可以自由執行其他工作。
使用異步 I/O 可讓導管伺服器使用執行下列步驟的循環:
- 在呼叫 wait 函式時指定多個事件物件,並等候其中一個物件設定為訊號狀態。
- 使用 wait 函式的傳回值來判斷哪些重疊作業已完成。
- 執行清除已完成作業所需的工作,並起始該管道句柄的下一個作業。 這可能需要為相同的管道控點啟動另一個重疊的作業。
重疊的作業可讓一個管道同時讀取和寫入數據,以及單一線程在多個管道控點上執行同時 I/O 作業。 這可讓單個線程管道伺服器有效率地處理與多個管道客戶端的通訊。 如需範例,請參閱使用重疊 I/O 命名管道伺服器。
若要讓管道伺服器使用同步作業與多個用戶端通訊,它必須為每個管道用戶端建立個別的線程,讓一或多個線程可以在其他線程等候時執行。 如需使用同步作業的多線程管道伺服器的範例,請參閱 多線程管道伺服器。
啟用異步作
ReadFile、WriteFile、TransactNamedPipe和 ConnectNamedPipe 函式,只有在您啟用指定管道句柄的重疊模式,並指定 OVERLAPPED 結構的有效指標時,才能以異步方式執行。 如果 重疊 指標 NULL,則函式傳回值可能會錯誤地指出作業已完成。 因此,強烈建議您使用 FILE_FLAG_OVERLAPPED 建立句柄並想要異步行為,您應該一律指定有效的重疊 結構。
所指定 重疊 結構的 hEvent 成員必須包含手動重設事件物件的句柄。 這是由 createEvent函式所建立的同步處理物件。 起始重疊作業的線程會使用事件對象來判斷作業完成時間。 當您在同一個句柄上執行同時作業時,您不應該使用管線句柄進行同步處理,因為無法知道哪個作業完成導致管道句柄收到訊號。 在相同管道控點上執行同時作業的唯一可靠技術,是針對每個作業使用個別的 重疊 結構與它自己的事件物件。 如需事件對象的詳細資訊,請參閱同步處理 。
此外,您可以使用 getQueuedCompletionStatus 或 GetQueuedCompletionStatusEx 函式,在重迭作業完成時收到通知。 在此情況下,您不需要在重疊結構指派手動重設事件,而且完成作業的方式與異步讀取或寫入作業相同。 如需詳細資訊,請參閱 I/O 完成埠。
ReadFile、WriteFile、TransactNamedPipe和 ConnectNamedPipe 作業以異步方式執行時,會發生下列其中一項:
- 如果函式傳回時作業完成,傳回值會指出作業的成功或失敗。 如果發生錯誤,傳回值為零,而且 getLastError函式會傳回ERROR_IO_PENDING以外的值。
- 如果函式傳回時作業尚未完成,則傳回值為零,GetLastError 傳回ERROR_IO_PENDING。 在此情況下,呼叫端線程必須等到作業完成為止。 呼叫端線程接著必須呼叫 getOverlappedResult函式,以判斷結果。
使用完成例程
ReadFileEx 和 WriteFileEx 函式提供另一種重疊 I/O 形式。 不同於重疊 ReadFile 和 WriteFile 函式,這些函式會使用事件對象來發出完成訊號,擴充函式會指定 完成例程。 完成例程是當讀取或寫入作業完成時排入佇列以供執行的函式。 完成例程不會執行,直到呼叫 ReadFileEx 和 WriteFileEx 的線程,藉由呼叫其中一個 可警示的等候函式,將 fAlertable 參數設定為 TRUE ,來啟動可警示的等候 作業。 在可警示的等候作業中,當 ReadFileEx 或 WriteFileEx 完成例程排入佇列執行時,函式也會傳回 。 管道伺服器可以使用擴充函式,為每個連線到它的客戶端執行一連串的讀取和寫入作業。 序列中的每個讀取或寫入作業都會指定完成例程,而每個完成例程都會起始序列中的下一個步驟。 如需範例,請參閱使用完成例程 命名管道伺服器。