簡體   English   中英

雙工模式下名為 pipe 的 Win32 的行為

[英]Behavior of Win32 named pipe in duplex mode

嘗試通過一個名為 pipe 的單服務器和單客戶端之間的讀寫,沒有重疊模式。 正在運行兩個線程分別進行讀取和寫入。 根據文檔,我的理解是,單個連接將同時具有輸入和輸出緩沖區。 所以我應該能夠使用 pipe 的單個實例並行讀寫。 編寫了一個簡單的測試代碼,以循環方式從服務器寫入客戶端。 服務器上的讀取線程調用 ReadFile 的那一刻,寫入線程卡在 WriteFile 上。 有人可以解釋這種情況下的行為嗎?

文檔說“在 pipe 客戶端啟動之前,pipe 服務器不應執行阻塞讀取操作”。 但是在客戶端開始從寫入線程接收數據之后,正在完成阻塞 ReadFile。

更新 1:我知道 ReadFile 在這里阻止了 WriteFile。 但我正在尋找 Microsoft 的文檔來解釋這種行為。 任何鏈接將不勝感激。

服務器上的讀取線程調用 ReadFile 的那一刻,寫入線程卡在 WriteFile 上。

一個 pipe 被兩個 kernel 文件對象引用(參見FILE_OBJECT ),在 pipe 的每一端都有一個。 在服務器端, CreateNamedPipe內部調用本機系統 function NtCreateNamedPipeFile ,在 kernel 中調用IoCreateFileCreateFileType作為CreateFileTypeNamedPipe傳遞。

每個文件 object 可以為同步或異步 I/O打開。 (異步 I/O 也稱為重疊 I/O。)I/O 模式取決於文件 object 中是否存在FO_SYNCHRONOUS_IO標志。 如果設置了標志,則 I/O 模式是同步的。 否則 I/O 模式是異步的。

對於同步模式,I/O 管理器序列化文件 object 上的所有 I/O 操作。 其他線程中對文件的並發 I/O 操作將阻塞(即等待開始),直到當前操作完成。 即使查詢文件名(也是 I/O 操作)也會阻塞。 (這是 Sysinternals handle.exe 等系統級工具的一個已知問題。如果我們在系統等待同步讀取完成時嘗試查詢 pipe 名稱,這可能會阻塞。)

使用多個線程(例如在一個線程中讀取,在另一個線程中寫入)在這里根本沒有幫助。 異步 I/O 在這里是理想的。 它更高效(線程更少)並且永遠不會死鎖。


原生 NT API 和 Windows API 使用不同的選項來指定 I/O 模式。

NT API(例如NtCreateFileNtCreateNamedPipeFile )默認采用異步模式。 使用同步模式需要一個特定的創建選項,如文檔中所述:

FILE_SYNCHRONOUS_IO_ALERTFILE_SYNCHRONOUS_IO_NONALERT CreateOptions標志,顧名思義是互斥的,指定文件上的所有 I/O 操作將是同步的——只要它們通過返回的 FileHandle 引用的文件 object 發生。 使用返回的句柄跨所有線程對此類文件上的所有 I/O 進行序列化。

使用任一創建選項,在文件 object 中設置FO_SYNCHRONOUS_IO標志。 FILE_SYNCHRONOUS_IO_ALERT額外設置FO_ALERTABLE_IO標志。

Windows API(例如CreateFileW , CreateNamedPipeW , CreatePipe )默認采用同步 I/O 模式。 為此,它在調用底層 NT API 函數時傳遞 NT 創建選項FILE_SYNCHRONOUS_IO_NONALERT Windows API 標志FILE_FLAG_OVERLAPPED覆蓋默認值以請求異步 I/O 模式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM