读取异步管道 - 丢失数据

Cal*_*602 5 c winapi multithreading asynchronous pipe

我想从管道中读取数据.读取不能阻塞主线程(所以一切都在一个单独的线程中),并且它必须是可取消的(因此我使用带FILE_FLAG_OVERLAPPED标志的重叠IO )

以下代码已简化,但我只删除了错误检查:

pipe = CreateNamedPipe("\\\\.\\pipe\\pipename", PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED , 0, 1, 1024, 1024, 1000, NULL);

while (1) {
  // wait for either new data, or cancellation
  DWORD wait = WaitForMultipleObjects(2,events,FALSE,INFINITE);

  // Assume "new data event" and no error

  GetOverlappedResult(pipe,&overlap,&unused,FALSE); // always succeeds
  ReadFile(pipe,outputbuffer,neededsize,outputsize, &overlap); // sometimes says ERROR_IO_PENDING via GetLastError()
}
Run Code Online (Sandbox Code Playgroud)
  • 正确接收第一个缓冲区.
  • 几秒钟内没有数据发送
  • 这似乎标志着这一事件.没有数据被读取(没有被发送!)和ReadFile()集合ERROR_IO_PENDING.
  • 发送另一组数据
  • ReadFile 丢失了一些新数据.

要精确,最后ReadFile()我在请求失去尽可能多的数据前面 ReadFile().

我做错了什么?

强制性参考

编辑 - 正确的方式,再次没有错误检查:

BOOL res = ReadFile(...as before...);
if(res)
    return; //success, reading was instantaneous, there was already data.
//GetLastError() is supposed to be ERROR_IO_PENDING here
wait = WaitForMultipleObjects(2,events,FALSE,INFINITE);
// Assume "new data event" and no error
res = GetOverlappedResult(pipe, &overlap, &cbRet, FALSE);
// Now the buffer you gave to ReadFile has its cbRet first bytes filled.
Run Code Online (Sandbox Code Playgroud)