我遇到挂起WaitNamedPipe功能的问题。 ...这是我的代码中与问题相关的部分。我创建了一个进程,然后是一个管道,而WaitNamedPipe函数似乎停留在FALSE上,因此挂起。 waitnamedpipe函数等待CC进程启动。
PROCESS_INFORMATION po;
STARTUPINFO s;
GetStartupInfo (&s);
if(CreateProcess ("c:\\s2.exe", NULL, NULL, NULL, false, 0, NULL, NULL, &s, &po) == FALSE)
{
printf("Error %d starting CC\n", GetLastError());
exit(-1);
}
HANDLE pipe=CreateNamedPipe ("\\.\pipe\CC-"+po.dwProcessId, 0x00000003, 0x40000000,
0x00080000L, 0x00000004, 128, 0, NULL);
while (WaitNamedPipe ("\\.\pipe\CC-"+po.dwProcessId, INFINITE) == FALSE )
Sleep (300);
*编辑我改了一些......但是它仍然挂起
PROCESS_INFORMATION po; STARTUPINFO s;
GetStartupInfo (&s);
if(CreateProcess ("c:\\s2.exe", NULL,
NULL, NULL, false, 0, NULL, NULL, &s,
&po) == FALSE) {
printf("Error %d starting CC\n", GetLastError());
exit(-1);
}
HANDLE pipe=CreateNamedPipe(pipe_name, 0x00000003,
FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_UNLIMITED_INSTANCES,128, 128, 0,
NULL);
while(WaitNamedPipe(pipe_name, INFINITE)==FALSE)
Sleep(300);
HANDLE CC = CreateFile (pipe_name,
GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
NULL);
bool fConnected = ConnectNamedPipe(pipe, NULL) ? TRUE :
(GetLastError() == ERROR_PIPE_CONNECTED);
if(fConnected) printf("true"); else printf("false");
答案 0 :(得分:3)
您会混淆命名管道的客户端和服务器端。服务器(管道的供应商)将调用CreateNamedPipe来创建管道。然后,为了等待客户端,它可以调用ConnectNamedPipe(但要注意,如果在此调用之前已经连接到它的客户端,它将立即返回GetLastError()== ERROR_PIPE_CONNECTED。)
客户端可以调用CreateFile(Not CreateNamedPipe)来打开实例。如果失败,则表示服务器实例不可用,因此客户端可以调用WaitNamedPipe以获得有关何时可用的通知。
MSDN上的一个很好的参考是Named Pipe Client示例和Multithreaded Pipe Server示例。
编辑:杰瑞指出的所有问题都属实。我指的是他所指的“管道逻辑”。
答案 1 :(得分:3)
你可能有其他人,但这里有两个问题:
"\\.\pipe\CC-"+po.dwProcessId
首先,反斜杠字符在C和C ++字符串中充当转义字符,因此源代码中需要两个反斜杠才能在字符串本身中提供一个反斜杠。所以,首先,你的字符串必须是:
"\\\\.\\pipe\\CC-"
第二个问题是+po.dwProcessId
部分。 "\\.\pipe\CC-"
部分给出了指向静态字符串开头的指针。然后,您将dwProcessId
的值添加到该指针。如果你的进程ID恰好是一个小于字符串的数字,那么它会在字符串的后面给出一个指针(例如,如果碰巧是2,它会产生一个指向".\\pipe\\CC-"
的指针,跳过两个前导反斜杠。如果(通常是这种情况),进程ID恰好是一个比字符串长度大的数字,你将获得一个指向你根本不拥有的内存的指针,并且没有知道它可能包含什么。
这意味着您向CreateNamedPipe
提供的名称基本上肯定是无效的。由于无法创建命名管道,WaitNamedPipe
将立即返回false - 正是您观察到的行为。
你可以尝试更像这样的东西:
char pipe_name[32];
sprintf(pipe_name, "\\\\.\\pipe\\CC-%d", po.dwProcessId);
HANDLE pipe = CreateNamedPipe(pipe_name, /* ... */);
WaitNamedPipe(pipe, NMPWAIT_WAIT_FOREVER);
我还没有对它进行测试,但这应该至少有一点接近工作的机会。我完全不确定你的命名管道逻辑是否正确,但至少这应该让你能够以一种有意义的方式开始研究它。