Windows:redirectinput和输出的subprocess

我正在尝试创build一个带有redirectinput和输出的subprocess(如此处所述 – http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx )。

对于那些不希望阅读该页面源代码的人来说,作者正在使用匿名pipe道redirect孩子的input和输出。 父进程写入subprocess的input并读取subprocess的输出。

然而,在那个代码中,程序在读写之后closures了pipe道(在WriteToPipe和ReadFromPipe中),所以实际上程序只是读取一个文件,将它转储到subprocessinputstream中,然后读取subprocess响应。

现在,我正在寻找的是一个代码,我们不会closurespipe道,但是我们会不断发布请求并读取subprocess响应(与只发出一个请求相反)。

我已经尝试了上面提到的链接上给出的源代码的一些修改,但无论我尝试什么,在ReadFromPipe()函数中调用ReadFile()时程序总是挂起(它可能等待孩子退出 – 但正如我所说我喜欢得到孩子的回应,然后发送其他请求)。

任何想法如何我可以克服这一点?

更新:

任何人都可以告诉我,使用RedirectStandardInputRedirectStandardOutput的.NET Process类是否是一个好的select?

有完全相同的问题,并通过使用PeekNamedPipe (根据MSDN也适用于匿名读取管道)来解决它在每次调用ReadFile之前检查可用数据。 这消除了我得到的阻塞问题,并允许我的GetExitCodeProcess()看到进程已退出并清理管道。

是的 – 如果使用RedirectStandardInputRedirectStandardOutput ,则.Net Process类会使用匿名管道重定向子进程的标准输入/输出,这与链接示例类似,所以这可能是一个相当不错的选择。

至于为什么ReadFile挂起 – 这听起来像这个函数正在等待子进程发送一些数据回来,或关闭管道。 如果你想不断地发送请求到子进程,那么你需要:

  • 确切地知道什么时候阅读是合适的,这样你就不会在子进程中等待/阻塞(例如,只有在发送请求后才能立即阅读)。 这个策略是非常危险的,因为总是有一个机会,孩子的过程不像预期的那样行事,你只能无限期地等待子过程。

  • 有一个专门的线程阅读 – 如果你有一个专门的线程阅读,那么线程可以无限期地等待子进程,因为你的其他线程仍然能够发送请求,并正常运行没关系。 这种方法比第一种方法更复杂,但是正确的做法要更加健壮。 这种方法唯一的另一个缺点就是它要求你为每个子进程都有一个额外的读线程,这意味着如果你需要与大量的子进程进行通信的话,它不能很好地扩展。

  • 使用异步IO – 可以调用ReadFile函数,使得它总是立即返回,但是当读取完成时会通知您(我对这个工作的确切细节有点模糊,因为我更多用于C#)。 这就是所谓的异步IO ,它是这三种方法中功能最多的,因为它允许你与许多子进程进行通信,而不需要为每个子进程设置一个专用的线程。 但是,权衡是最正确的做法也是最复杂的(至少在我看来)。