我正在尝试使用重定向输入和输出创建子进程(如此处所述 - http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx)。
对于那些不想在该页面上阅读源代码的人,作者使用匿名管道来重定向孩子的输入和输出。父进程写入子进程的输入并从子进程的输出中读取。
然而,在该代码中,程序在读取和写入之后(在WriteToPipe和ReadFromPipe中)关闭管道,因此实际上程序只读取文件,将其转储到子进程输入流上,然后读取子进程响应。
现在,我正在寻找的代码是我们不会关闭管道的代码,但是我们将不断发布请求并读取子进程响应(与仅发出1个请求相反)。
我已尝试对上面发布的链接上给出的源代码进行了几处修改,但无论我尝试什么,程序总是在ReadFromPipe()函数中调用ReadFile()时挂起(它可能等待子进程退出 - 但正如我所说,我希望得到孩子的回应,然后向其发送其他请求。)
关于如何克服这个问题的任何想法?
至少有人能告诉我,使用带有RedirectStandardInput
和RedirectStandardOutput
的.NET Process类是一个不错的选择吗?
答案 0 :(得分:1)
有完全相同的问题,并通过使用PeekNamedPipe
(根据MSDN也适用于匿名读取管道)在每次调用ReadFile之前检查可用数据来解决它。这消除了我遇到的阻塞问题,并允许我的GetExitCodeProcess()
看到进程退出并清理管道。
答案 1 :(得分:0)
是的 - 如果您使用RedirectStandardInput
和RedirectStandardOutput
,.Net Process类会使用匿名管道以与链接示例非常相似的方式重定向子进程的标准输入/输出,因此这是可能是一个相当不错的选择。
至于为什么ReadFile
挂起 - 听起来这个函数正在等待子进程发回一些数据,或者关闭管道。如果您想继续将请求发布到子进程,则需要:
确切知道何时适合阅读,以便您不会等待/阻止子进程(例如,您只能在发送请求后立即阅读)。这种策略非常危险,因为子进程总是有可能没有按预期运行,并且您无限期地等待子进程。
有一个专用的线程可供阅读 - 如果你有一个专门的线程可供阅读,那么线程可能会无限期地等待子进程并不重要,因为你的其他线程仍在能够发送请求并正常运行。这种方法比第一种方法更复杂,但是如果正确完成则更加健壮。这种方法的唯一另一个缺点是它需要为每个子进程设置一个额外的读取线程,这意味着如果需要与大量子进程通信,它不能很好地扩展。
使用异步IO - 可以调用ReadFile函数,使其始终立即返回,但是在读取完成时会通知您(I'关于它如何工作的确切细节有点模糊,因为我更习惯于C#)。这被称为Asynchronous IO,并且是这3种方法中最通用的,因为它允许您与许多子进程通信,而不需要为每个进程提供专用线程。然而,权衡是它也是最复杂的(至少在我看来)。