gpt4 book ai didi

c++ - 如何正确读取子进程的 stdout/stderr 输出?

转载 作者:可可西里 更新时间:2023-11-01 10:09:38 26 4
gpt4 key购买 nike

我编写了一个程序a.exe,它启动了我编写的另一个程序b.exe,使用CreateProcess功能。调用者创建两个管道并将两个管道的写入端传递给 CreateProcess 作为 stdout/stderr 句柄以用于子进程。这实际上与 Creating a Child Process with Redirected Input and Output 相同MSDN 上的示例确实如此。

因为它似乎无法使用等待进程退出的同步调用 stdout 或 stderr 上的数据可用(WaitForMultipleObjects 函数不在管道上工作),调用者有两个线程正在运行,它们都执行(阻塞)ReadFile调用 stdout/stderr 管道的读取端;这是用于 stdout/stderr 的“读取线程过程”的确切代码(我自己没有写这段代码,我想是某个同事写的):

DWORD __stdcall ReadDataProc( void *handle )
{
char buf[ 1024 ];
DWORD nread;
while ( ReadFile( (HANDLE)handle, buf, sizeof( buf ), &nread, NULL ) &&
GetLastError() != ERROR_BROKEN_PIPE ) {
if ( nread > 0 ) {
fwrite( buf, nread, 1, stdout );
}
}
fflush( stdout );
return 0;
}

a.exe 然后使用一个简单的 WaitForSingleObject调用以等待 b.exe 终止。一旦该调用返回,两个读取线程终止(因为管道已损坏)并且两个管道的读取端使用 CloseHandle 关闭。 .

现在,我遇到的问题是:b.exe 可能(取决于用户输入)启动比 b.exe< 生命周期更长的外部进程 本身,基本上是守护进程。在这种情况下发生的情况是 stdout/stderr 管道的写入端被继承到该守护进程,因此管道永远不会被破坏。这意味着 a.exe 中的 WaitForSingleObject 调用返回(因为 b.exe 已完成)但是对任一管道的 CloseHandle 调用阻塞,因为两个读取线程仍在他们的(阻塞!)ReadFile 调用。

b.exe 返回后,我该如何解决这个问题而不用强力 ( TerminateThread ) 终止两个读取线程?如果可能的话,我也想避免任何涉及管道和/或进程轮询的解决方案。

更新:这是我目前所做的尝试:

  1. 没有b.exe继承a.exe;这是行不通的。 MSDN 特别指出传递给 CreateProcess 的句柄必须是可继承的。
  2. 清除 b.exe 中 stdout/stderr 上的可继承标志:似乎没有任何效果(如果有效果我会感到惊讶)。
  3. ReadDataProc 过程(在两个管道上读取)除了检查 ERROR_BROKEN_PIPE 之外,还考虑 b.exe 是否实际运行。这当然不起作用(但我后来才意识到),因为线程在 ReadFile 调用中被阻塞。

最佳答案

  1. 使用命名管道和异步ReadFile
    或者
  2. 解析从管道中读取的输出以寻找结尾(在您的情况下可能太复杂了)。

关于c++ - 如何正确读取子进程的 stdout/stderr 输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3164234/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com