关于c ++:使用WriteFile / ReadFile的死锁

Deadlock with WriteFile/ReadFile

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

1
2
3
4
5
6
7
8
9
10
11
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

首先创建管道,然后在另一个应用程序中使用它:

1
2
3
4
5
6
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

我收到以下信息:

1
2
3
4
5
6
        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放在单独的线程中以从中读取数据。我这样做是因为在发送邮件后我需要一个答案。


也许您有使用阻塞IO的问题。 对ReadFile的调用将阻塞,直到有需要读取的内容为止。 如果您有调用写然后读的循环,则它可能会在第二个调用中阻塞。
也许您应该考虑使用异步io。 您使用事件调用readFile。 当需要读取某些内容时,将设置该事件。 因此,无需创建多个线程。


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

参见http://msdn.microsoft.com/zh-cn/library/windows/desktop/aa365150(v=vs.85).aspx

编辑:对于"不得执行任何阻止读取操作":根据文档,这可能会导致竞争情况,这实际上可能是您的情况,但是,如果看不到更多代码,很难分辨出来。