【问题标题】:Deadlock with WriteFile/ReadFileWriteFile/ReadFile 死锁
【发布时间】:2011-10-14 06:42:26
【问题描述】:

我正在使用管道,但在 WriteFile/ReadFile 上遇到了一种死锁。这是我的代码:

hProbePipeRet = CreateNamedPipe( 
          "\\\\.\\pipe\\probePipeRet", // pipe name 
          PIPE_ACCESS_DUPLEX,       // read/write access 
          PIPE_TYPE_MESSAGE |       // message type pipe 
          PIPE_READMODE_MESSAGE |   // message-read mode 
          PIPE_WAIT,                // blocking mode 
          PIPE_UNLIMITED_INSTANCES, // max. instances  
          BUFSIZE,                  // output buffer size 
          BUFSIZE,                  // input buffer size 
          5,                        // client time-out 
          NULL);                    // default security attribute 

首先我创建了我的管道,然后我在另一个应用程序中像这样使用它:

WriteFile( 
            hProbePipeRet,        // handle to pipe 
            msg.c_str(),     // buffer to write from 
            msg.size(), // number of bytes to write 
            &dwBytesWritten,   // number of bytes written 
            NULL);        // not overlapped I/O 

然后我收到了:

        fSuccess = ReadFile( 
            myInst->hProbePipeRet,        // handle to pipe 
            buf,    // buffer to receive data 
            BUFSIZE, // size of buffer 
            &dwBytesRead, // number of bytes read 
            NULL);        // not overlapped I/O 

这是非常基本的,我还有两个完全一样的管道,唯一的区别是它们在不同的线程中,但我只需要这个用于消息的基本事务。

在第一次尝试时,管道上的信息被成功读取,但在第二次尝试时,如果我没有发送至少 BUFSIZE 的数据,WriteFile 和 ReadFile 都会阻塞。正如我所说,我还有两个管道做同样的事情,具有相同的功能,并且我不需要发送 BUFSIZE 的数据来进行成功的通信。

编辑:附加信息

执行如下: pipe1 向服务器发送一条消息,接收到该消息然后在我的有问题的代码中返回带有 hProbePipeRet 的数据。数据由客户端读取,打印到屏幕上。

使用 pipe1 发送另一条消息,接收到结果,结果再次出现在 hProbePipeRet 中,客户端正在等待至少 BUFSIZE 的信息,我不知道服务器在做什么,但它在 WriteFile 处被阻止。

这种情况与我的其他管道相同,但我没有将 hProbePipeRet 放在单独的线程中以从中读取。我这样做是因为我需要在发送消息后立即得到答复。

【问题讨论】:

  • 您应该考虑尝试构建一个可以在此处发布的最小示例,以便我们可以对其进行编译并重现您的问题。构建这样的示例还可以让您深入了解问题的原因。见sscce.org

标签: c++ file-io pipe named-pipes


【解决方案1】:

也许你有使用阻塞 IO 的问题。对 ReadFile 的调用会阻塞,直到有要读取的内容为止。如果您有一个调用 write 然后 read 的循环,它可能会在第二次调用中阻塞。 也许您应该考虑使用异步 io。您使用事件调用 readFile。当有要阅读的内容时,该事件被设置。所以不需要创建多个线程。

【讨论】:

    【解决方案2】:

    使用 PIPE_TYPE_BYTEPIPE_READMODE_BYTE 代替 MESSAGE 计数器部分。此外,在任何客户端连接之前,服务器不得执行任何阻塞读取操作。

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa365150(v=vs.85).aspx

    编辑:对于“不得执行任何阻塞读取操作”:根据文档,这可能会导致竞争条件,这实际上可能是您的情况,但是如果不查看更多代码就很难判断。

    【讨论】:

    • BYTE 模式不能解决我的问题。我可以提供的代码不多,但我编辑了我的消息以向您提供发生的场景。
    猜你喜欢
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    相关资源
    最近更新 更多