我想创建一个程序,可以为任何exe文件创建一个进程,同时捕获该exe文件的stderr和stdout,即重定向到我的程序。必须保留目标任意exe文件进程的输出顺序。即如果它向stdout发送10个char,然后向stderr发送10个char,然后向stdout发送10个char,我的程序需要认识到这个孩子在stderr和stdout之间交替而不是简单地将stderr和stdout视为2个独立的流。或者像这样:
stdout 10个字节, stderr 10个字节, stdout 10个字节, stderr 3个字节,... ......
我知道重定向stdout和stderr的标准方法是创建2个匿名管道,并使用创建的子进程继承的2个管道。但问题是匿名管道阻塞了i / o。如果我在父级中使用2个线程,一个用于读取子级的stdout,另一个用于读取子级的stderr,我无法判断子级在stdout和stderr之间交替,即上面列出的序列信息丢失。
编辑:
我正在为cl.exe,lib.exe和link.exe编写代理。与Mozilla开源项目(NSPR)捆绑在一起的构建系统使用一些非常独特的方法来构建源文件,以使其可跨多个平台移植并自动检测目标编译器的功能(即 autoconf 和 configure 脚本)。它在执行“make”时动态生成一些.h文件和#define。它甚至调用一些python脚本来调用cl.exe。
我不知道Mozilla构建系统正在做什么,也不知道为什么需要使用一些python脚本来调用cl.exe(它显然分析了cl.exe命令的stdout / stderr)。我不想花时间研究它。但我所知道的是它必须最终调用cl.exe,lib.exe和link.exe,这些命令的接口必须是命令行参数,env变量和stdout / stderr。所以我需要编写一个代理cl.exe,它调用真正的cl.exe并提供我自己的命令行arg,并尽可能透明地向调用者返回stderr和stdout。
cl.exe的特点是它可以在stdr中返回错误消息,在stdout中返回正常消息。我只想要一个透明的方法在真正的cl.exe和构建系统之间插入一个代理。
答案 0 :(得分:1)
我不确定你为什么要这样做,但你问的问题可以这样做:
每个流都有一个线程,两个线程共享公共队列或其他东西,一旦从流中读取字节,它们就会获得一个锁,并将某种对象放入公共队列。即使这样也不能保证正确性,但我想这样就足够了。
这种方法会产生巨大的开销,因为它会为每个读取字节创建对象。根据您期望的输出,可能等待整行更有意义。
您可能希望通过更具体的细节来扩展您的问题?
编辑:为什么不直接输出孩子的stdout和std err?