WaitNamedPipe只是挂起

时间:2011-01-28 04:12:35

标签: c++ c windows named-pipes

我遇到挂起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");

2 个答案:

答案 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);

我还没有对它进行测试,但这应该至少有一点接近工作的机会。我完全不确定你的命名管道逻辑是否正确,但至少这应该让你能够以一种有意义的方式开始研究它。