popen后台执行进程问题
本文最后更新于:2025年11月19日 下午
popen里面使用&后台进程问题
这个例子可以加深对linux下fork,文件等的理解
直接进入主题,如下代码
1 | |
问题
分别以./a.out和./a.out get运行结果是怎样?
- ping能在后台运行吗?
- a.out会立即退出吗?
- a.out能捕获到ping输出吗?
答案
(1)以 ./a.out 运行,ping不能再后台运行,a.out也会立即退出。
(2)以 ./a.out get运行,ping能在后台运行,a.out可以捕获到ping输出,a.out不会立即退出。
分析
原理
通过strace跟踪系统调用,分析如下:
popen原理
(1) 创建管道
(2)fork
(3)(子进程)将管道描述符dup到标准输入输出上
(4)(子进程)exec程序
(5)(父进程)(这是pclose调用)wait子进程
命令行程序后加&
fork两次,然后子进程退出,孙子进程运行命令行程序。
注意:fork的过程中,并没有去操作描述符
过程
先分析这个过程:以 ./a.out 运行,ping不能再后台运行,a.out也会立即退出。
(1)由于是后台运行ping,所以pclose会很快收到子进程退出,然后返回,a.out便退出了。注意:这是popen创建的管道读端便关闭了。
(2)ping程序运行时,标准输出为a.out的管道写端描述符。当ping程序输出时,会失败,因为a.out已经退出,管道的读已经关闭,会收到SIGPIPE信号,默认动作就是退出。所以ping并不能在后台一直运行。
再分析这个过程:以 ./a.out get运行,ping能在后台运行,a.out可以捕获到ping输出,a.out不会立即退出。
和前面类似,子进程虽然已经退出,但孙子进程ping也随着fork复制了这个管道,子进程关闭管道读只是把引用计数-1,并不会真正关闭读管道,所以a.out进程可以一直读。a.out不退出,ping自然可以向管道输出,持续执行,不会遇到SIGPIPE信号。