侧边栏壁纸
  • 累计撰写 74 篇文章
  • 累计创建 45 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Windows Named Pipe 如何提前终止ConnectNamedPipe的同步等待

码峰
2022-08-29 / 0 评论 / 0 点赞 / 203 阅读 / 391 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-08-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

问题描述

在Windows中使用命名管道Named Pipe进行跨进程通信时,在Server端用ConnectNamedPipe同步等待(非异步模式),如果没有Client连接,这个等待就会一直进行下去,等待过程中调用CloseHandle尝试关闭Pipe的句柄,CloseHandle也会被阻塞掉,有时候我们希望提前结束ConnectNamedPipe怎么办呢?

解决办法

ConnectNamedPipe的同步等待,只有当有Client通过CreateFile的方式进行连接时,才会退出,所以,我们通过CreateFile和额外的Event来提前终止连接,首先在初始时创建Event:

    g_NamedPipeStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (g_NamedPipeStopEvent == NULL)
    {
        //error processing
    }

然后,创建如下函数:

void StopNamedPipe()
{
    SetEvent(g_NamedPipeStopEvent);
    HANDLE hPipe = CreateFile(pipeName,
    GENERIC_READ | GENERIC_WRITE,
    0, NULL, OPEN_EXISTING, 0, NULL);
    if (hPipe != INVALID_HANDLE_VALUE) {
        CloseHandle(hPipe);
    }
}

这个函数的功能就是在当我们要提前终止ConnectNamedPipe时调用,在ConnectNamedPipe处修改代码如下:

    BOOL ret = ConnectNamedPipe(pipeHandle, NULL); //阻塞等待客户端连接。
    if (WaitForSingleObject(g_NamedPipeStopEvent, 0) == WAIT_OBJECT_0) {
        //执行到这里表示是通过调用StopNamedPipe()连接的,则这里开始执行退出的操作
        return 0;
    }

总结

ConnectNamedPipe同步方式,除了通过CreateFile进行连接以外,没有其他方法能够提前终止,我们通过Event是否被Set,来判断到底是正常的Client连接还是调用了StopNamedPipe()函数,希望提前终止,从而间接实现了提前终止ConnectNamedPipe的功能。

0

评论区