替代popen/pclose的方法有哪些?

5
我正在编写一个程序,需要执行其他外部进程;目前该程序通过popen启动进程的命令行,获取任何输出,然后通过pclose获取退出状态。
然而,对于运行速度快的进程(例如,启动的进程很快出错),pclose调用无法获取退出状态(pclose返回-1,errno为ECHILD)。
有没有一种方法可以模拟popen/pclose类型的行为,但以保证捕获进程结束“事件”和结果返回代码的方式?如何避免pclose和启动进程的终止之间固有的竞争条件?
2个回答

3

fork/exec/wait

fork, exec和wait是IT技术中常用的三个系统调用。其中,fork用于创建一个新进程,该进程是原始进程的副本。exec用于在进程中执行一个新程序。wait用于等待子进程退出,并获取其退出状态。

popen只是一个简化fork/exec调用的包装器。如果您想获取子进程的输出,则需要创建一个管道,调用fork,将子进程的文件描述符复制到管道中,然后执行。父进程可以从管道中读取输出,并调用wait以获取子进程的退出状态。


4
由于Windows操作系统没有fork,因此popen在Windows上可用,显然并不总是一个包装器。 - anon
我重写了我的代码来实现这个(fork/exec/dup等),但是现在我偶尔会遇到waitpid(...)返回-1/errno=ECHILD的失败。糟糕。 - Joe
3
好的:我弄清楚了。这段代码很好用。我的旧代码使用popen/pclose也非常好用。不好的是隐藏的SIGCHLD处理程序,它深藏在我继承的通用代码中。天哪。我基本上在与该处理程序竞争(它只是调用waitpid(-1,...)。教训是:阅读所有的man手册,并不要假设任何东西! - Joe

1
你可以使用vfork()和execv()。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接