2013-02-14 56 views
0

我正在使用I/O完成端口进程管理库(是的,这是有原因的)。你可以在这里找到我在说的东西的来源:https://github.com/jcommon/process/blob/master/src/main/java/jcommon/process/platform/win32/Win32ProcessLauncher.java(看看第559行和第1137行 - 是的,这个类需要重构和清理)。I/O完成端口和stdout处理

为了处理子进程的stdout和stderr,我正在启动子进程并使用命名管道(不是匿名管道b/c我需要异步,重叠的ReadFile()/ WriteFile())。这主要是实际工作。在一项测试中,我启动了1,000个并发进程并监视它们的输出,确保它们发出正确的信息。通常情况下,所有1,000人工作正常或998人,留下一对有问题的夫妇。

这几对进程显示并非所有的消息都被接收到。我知道该消息正在输出,但该进程的线程处理GetQueuedCompletionStatus()从ERROR_BROKEN_PIPE读取返回。

预期的行为是操作系统(或C库)会在进程退出时刷新标准输出缓冲区上的剩余字节。然后,我会希望这些字节排队到我的iocp之前得到一个坏的管道错误。相反,这些字节看起来消失了,并且读取完成了一个ERROR_BROKEN_PIPE--在我的代码中,这会导致它启动子进程的拆卸。

我写了一个简单的应用程序来测试并找出行为(https://github.com/jcommon/process/blob/master/src/test/c/stdout-1.c)。此应用程序禁用标准输出缓冲,因此所有写入操作应立即刷新。在我的测试中使用该程序会产生与启动“cmd.exe/c echo hi”相同的问题。无论如何,当进程退出时,应用程序(或OS?)不应该在stdout中刷新剩余的字节吗?

该源代码是使用直接映射JNA的Java,但对于C/C++工程师来说应该相当容易。

感谢您提供任何帮助!

回答

0

是否确定在非零ioSize中没有发生管道故障错误?如果ioSize不为零,则应该处理读取的数据以及注意该文件现在已关闭。

我的C++代码基本上忽略了ERROR_BROKEN_PIPEERROR_HANDLE_EOF,只是等待下一次读取尝试失败,出现上述错误之一或者当前读取完成时读取零字节。有问题的代码适用于文件和管道,我从来没有看到您在运行您描述的那种测试时所描述的问题。