使用popen运行程序时如何获取其pid或终止该运行进程?
popen进程PID获取与终止方案
PID获取方法
popen标准接口没有直接返回子进程PID的能力,但可以通过不需要改动原有调用结构的方法实现:
- 最通用的跨Unix/Linux/macOS方案:修改你传给popen的命令字符串,在原有命令前套一层shell,先输出当前shell的PID,再用exec替换为目标程序,PID不会改变:
原命令示例(以ffmpeg场景为例):popen("ffmpeg -i rtsp://xxx/stream -c:v copy output.flv", "r")
修改后命令:popen("sh -c 'echo $$; exec ffmpeg -i rtsp://xxx/stream -c:v copy output.flv'", "r")
调用popen后读取返回流的第一行内容,就是目标ffmpeg进程的PID,后续流内容和修改前完全一致,不影响原有业务逻辑。 - Windows平台适配:可以改成套cmd实现PID输出:
popen("cmd /c \"echo %PID% & ffmpeg -i rtsp://xxx/stream -c:v copy output.flv\"", "r") - 如果你完全不能修改执行的命令内容,可以通过遍历系统进程列表匹配特征的方式定位PID:你用的是ffmpeg,可以匹配进程名+命令行中的编码参数特征,Unix下读
/proc目录即可,Windows下调用tasklist或WMI接口实现。
进程终止方法
- 如果你已经拿到了目标进程PID:
- Unix/Linux/macOS下调用
kill(<PID>, SIGTERM)即可发送终止信号,如果进程无响应可以换SIGKILL强制终止,终止后再调用pclose()回收管道资源即可 - Windows下执行命令
taskkill /PID <PID> /F强制终止即可
- Unix/Linux/macOS下调用
- 如果你没有拿到PID,针对ffmpeg场景可以直接按特征批量匹配终止:
- Unix/Linux/macOS执行
pkill -f "ffmpeg.*<你的流地址/编码特征参数>" - Windows执行
taskkill /F /IM ffmpeg.exe /FI "COMMANDLINE eq *<你的流地址/编码特征参数>*"
- Unix/Linux/macOS执行
注意:不要直接调用
pclose()终止正在运行的进程,该函数只会阻塞等待进程主动退出,不会主动发送终止信号,无法满足你手动停止的需求。
内容的提问来源于stack exchange,提问作者SweetNGX
相关产品推荐
相关产品推荐

