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

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

一切都运行良好,除了在两个管道上的一些写/读周期后,当孩子结束时,调用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(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); ... } ... 

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

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

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

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

在您的情况下一切都很好,您可以访问管道上的两个进程。 如果你没有,或者只想中断ReadFile调用,那么CancelSynchronousIo就是你的朋友: https : CancelSynchronousIo ( v = CancelSynchronousIo )。 ASPX