即使在孩子终止后,Win32,来自管道块的ReadFile

Art*_*Ale 11 c pipe win32-process

我有一个简单的程序(在C中)创建两个子进程,每个等待一个继承的管道,并将输出放在一个文件中.

一切都运行良好,除了在两个管道上的一些写/读周期后,当孩子结束时,调用ReadFile块,等待管道上的数据.我使用以下模式:

...
//create pipe1
CreatePipe(&hReadDup,&hWrite,&saAttr,0);
DuplicateHandle(GetCurrentProcess(),hReadDup,GetCurrentProcess(),&hRead,0,FALSE,DUPLICATE_SAME_ACCESS);
CloseHandle(hReadDup);


si.cb = sizeof(si);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hWrite;   

CreateProcess(  NULL,
        const_cast<LPWSTR>(cmd2.c_str()), //the command to execute
        NULL,
        NULL,
        TRUE,
        0,
        NULL,
        NULL,
        &si, //si.
        &pi
    );

...
CloseHandle(hWrite); // EDIT: this was the operation not properly done!

while(cont){
    ...
    cont = ReadFile(hRead,buf,50, &actual,NULL);
    ...
}
... 
Run Code Online (Sandbox Code Playgroud)

最后一次调用(子进程退出后)阻止.想法为什么(如果不是,如何调试)?

Art*_*Ale 13

我自己找到了解决方案(实际上是编码错误).我没有正确关闭父管道的管道写入句柄(hWrite),因此,同步ReadFile无法报告子进程终止.

如果有人遇到同样的问题,请确保在启动该管道上的I/O操作之前关闭管道的可继承句柄(如MSDN报告,再也找不到).

  • 关于这个问题的一些有用的文档:http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365782(v = vs.85).aspx (2认同)
  • 感谢您的回答。Microsoft 自己的代码示例 [1] 已损坏,但这为我解决了问题。[1]:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx (2认同)

Rem*_*eau 7

您正在ReadFile()以同步模式呼叫.只要管道打开,ReadFile()就会阻塞等待更多数据.如果您保持打开CreateProcess()返回给您的进程和线程句柄,这将阻止子进程完全退出,因此管道可能无法在子端关闭.在进入读取循环之前,关闭CreateProcess()返回的句柄,允许管道在子进程完全终止时正确关闭,然后ReadFile()在无法再从管道读取时向您报告错误.或者,切换到管道上的重叠I/O,这样您就可以在循环运行时WaitForSingleObject()GetExitCodeProcess()在循环运行时监视子进程,这样您就可以检测子进程何时终止,而不管管道状态如何.