非阻塞ConnectNamedPipe事件没有得到信号

Non-blocking ConnectNamedPipe event not getting signaled

本文关键字:信号 事件 ConnectNamedPipe      更新时间:2023-10-16

我从命名管道开始,需要将它们用于两个本地进程之间的IPC。我让服务器和客户端进程都以非阻塞重叠模式使用管道。

一切正常(服务器成功接收客户端发送的字符串),除了通过OVERLAPPED结构传递给ConnectNamedPipe()的事件没有像预期的那样获得信号(当客户端连接时发出信号)。

当服务器被WaitForSingleObject()阻塞时,调用连接到管道的客户端进程,发送其数据并终止,但事件没有得到信号。我错过了什么?

服务器代码:

HANDLE hPipe = ::CreateNamedPipeW(
    L"\\.\pipe\ThePipe",
    PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
    PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT,
    1,
    4096,
    4096,
    100,
    nullptr);
OVERLAPPED ov = {0};
ov.hEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr);
BOOL retVal = ::ConnectNamedPipe(hPipe, &ov);
if (retVal == 0)
{
    DWORD err = ::GetLastError();
    if (err == ERROR_IO_PENDING)
    {
        ::WaitForSingleObject(ov.hEvent, 30000);
    }
    if (err == ERROR_PIPE_LISTENING)
    {
        ::WaitForSingleObject(ov.hEvent, 30000);    // this blocks until time-out???
    }
}

您不应该将(已弃用的)PIPE_NOWAIT与重叠模式一起使用。如果没有客户端连接,PIPE_NOWAIT使ConnectNamedPipe立即返回ERROR_PIPE_LISTENING;重叠的I/O不会发生,等待事件是没有用的。

设置PIPE_NOWAIT并定期轮询管道直到成功,或者设置FILE_FLAG_OVERLAPPED并使用事件检查/等待完成。