Re: [問題] IPC的選擇
推
01/26 00:43,
01/26 00:43
→
01/26 00:44,
01/26 00:44
→
01/26 00:44,
01/26 00:44
→
01/26 00:50,
01/26 00:50
建立 named pipe (具名管線) 是用 CreateNamedPipe() 函數,在伺服端第一次指名
要建管線名稱 "purpose" 時,會返回第一個 "instance" 的參考,假設是 hPipe。
此時繼續使用 HANDLE hPipe2 = CreateNamedPipe(..) 可得到第二個 "instance"。
然後你 ConnectNamedPipe(hPipe, NULL) 完再 ConnectNamedPipe(hPipe2, NULL)
就同時連接兩個客戶端了,沒有第二個讀不到。
→
01/26 01:01,
01/26 01:01
→
01/26 01:02,
01/26 01:02
甲端把資料輸出到 named pipe:
對於乙端來說,等於是自己的 Input 區被填入,
若同時間乙端把資料也輸出到同一個 named pipe,則是寫入到自己的 Output 區。
根本就不同位置。
推
01/26 01:13,
01/26 01:13
→
01/26 01:13,
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)
推
01/26 10:35, , 1F
01/26 10:35, 1F
推
01/27 14:36, , 2F
01/27 14:36, 2F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章