看板 C_and_CPP 關於我們 聯絡資訊
QQ29:看named pipe 假設同時有兩個client readfile...01/26 00:43
QQ29:他會讓第一個讀完 看註解server就exit了 然後第二個就讀不到01/26 00:44
QQ29:覺得很怪...還是說server要while一直重創pipe...01/26 00:44
QQ29:我自己試試看 感覺好像是一次性的 同時讀"好像"一個拿不到01/26 00:50
建立 named pipe (具名管線) 是用 CreateNamedPipe() 函數,在伺服端第一次指名 要建管線名稱 "purpose" 時,會返回第一個 "instance" 的參考,假設是 hPipe。 此時繼續使用 HANDLE hPipe2 = CreateNamedPipe(..) 可得到第二個 "instance"。 然後你 ConnectNamedPipe(hPipe, NULL) 完再 ConnectNamedPipe(hPipe2, NULL) 就同時連接兩個客戶端了,沒有第二個讀不到。
QQ29:自己可能還要試試看 若client連上後去write pipe會不會蓋掉01/26 01:01
QQ29:server原本寫的...然後就deadlock? 沒人讀(若只有一條thread)01/26 01:02
甲端把資料輸出到 named pipe: 對於乙端來說,等於是自己的 Input 區被填入, 若同時間乙端把資料也輸出到同一個 named pipe,則是寫入到自己的 Output 區。 根本就不同位置。
QQ29:測試發現server writefile若client有讀過, server第二次01/26 01:13
QQ29:write就完全不會block 滿奇怪的..感覺pipe真的只能用一次.. 01/26 01:13
能用很多次,這是緩衝區不夠大,只要空間夠,可以連續做 WriteFile 的動作, 不管對方有沒有讀過。 下面我提供一份範例,流程是這樣: 1. 伺服端啟動,並且開始監聽連線 2. 客戶端啟動,雙方以 named pipe 連線成功 3. 雙方同時進行寫入資料的動作,其中客戶端會連續做三次 write pipe 4. 伺服端睡眠 8 秒,然後才對 named pipe 做唯一一次的讀取 伺服端執行畫面 server is listening... numBytes for writefile = 8 sleeping... numBytes for writefile = 8 numBytes for readfile = 68 AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBC 客戶端執行畫面 numBytes for writefile = 32 numBytes for writefile = 32 numBytes for writefile = 4 all done, stop... ######## 線上程式碼:http://ideone.com/z2pRRF /* filename: pipe_server.c */ #define UNICODE #include <windows.h> #include <stdio.h> int main() { wchar_t buf[1024]; int numBytes = 0; BOOL writeGood = FALSE; HANDLE hPipe = NULL; hPipe = CreateNamedPipe(L"\\\\.\\pipe\\purpose", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE, 1, 512, /* out-buf size */ 512, /* in-buf size */ 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { _putws(L"hPipe error.\n"); return 0; } puts("server is listening..."); if (ConnectNamedPipe(hPipe, NULL) == TRUE) { writeGood = WriteFile(hPipe, L"^_^", 8, &numBytes, NULL); printf("numBytes for writefile = %d\n", numBytes); if (writeGood == FALSE) return 0; _putws(L"sleeping..."); Sleep(8000); writeGood = WriteFile(hPipe, L">_<", 8, &numBytes, NULL); printf("numBytes for writefile = %d\n", numBytes); if (writeGood == FALSE) return 0; ReadFile(hPipe, buf, 1024 * sizeof(wchar_t), &numBytes, NULL); printf("numBytes for readfile = %d\n", numBytes); _putws(buf); } FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle(hPipe); return 0; } ######## ==================== 線上程式碼:http://ideone.com/FRZgJr /* filename: pclient.c */ #define UNICODE #include <windows.h> #include <stdio.h> int main() { wchar_t buf[1024]; int numBytes = 0; BOOL writeGood = FALSE; HANDLE hPipe = NULL; hPipe = CreateFile(L"\\\\.\\pipe\\purpose", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPipe == INVALID_HANDLE_VALUE) { _putws(L"hPipe error.\n"); return 0; } writeGood = WriteFile(hPipe, L"AAAAAAAAAAAAAAAA", 32, &numBytes, NULL); printf("numBytes for writefile = %d\n", numBytes); if (writeGood == FALSE) return 0; Sleep(500); writeGood = WriteFile(hPipe, L"BBBBBBBBBBBBBBBB", 32, &numBytes, NULL); printf("numBytes for writefile = %d\n", numBytes); if (writeGood == FALSE) return 0; Sleep(500); writeGood = WriteFile(hPipe, L"C", 4, &numBytes, NULL); printf("numBytes for writefile = %d\n", numBytes); _putws(L"all done, stop..."); system("pause"); CloseHandle(hPipe); return 0; } ==================== 把原始碼中的 512, /* in-buf size */ 改成比如 12 (bytes) 則客戶端第二次 write pipe 就會失敗,重現最上面推文提到的問題。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.8.138.160 補充 MSDN 資料: Every time a named pipe is created, the system creates the inbound and/or outbound buffers using nonpaged pool, which is the physical memory used by the kernel. The number of pipe instances (as well as objects such as threads and processes) that you can create is limited by the available nonpaged pool. 即 named pipe 在同一台電腦上,直接使用 kernel 的記憶體,不必用硬碟檔案做映射。 ※ 編輯: purpose 來自: 124.8.138.160 (01/26 06:53)
suhorng:推 01/26 10:35
cobrasgo:這個thread好像很有趣,可惜windows完全不熟插不上話囧 01/27 14:36