雷达智富

首页 > 内容 > 程序笔记 > 正文

程序笔记

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

2024-08-24 82

问题描述

在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的功能。

更新于:2个月前
赞一波!4

文章评论

评论问答