C++如何关闭通过system函数打开的gedit等外部程序
实现方案
原有代码问题说明
system("gedit ./fileName")默认同步阻塞执行,必须等gedit退出才会返回,因此后续休眠、关闭逻辑无法执行system("^C")是无效调用,^C是终端触发SIGINT信号的快捷键,不是可执行的shell命令- 休眠写法有误,正确写法为
std::this_thread::sleep_for(std::chrono::seconds(10))
方案1:简易shell调用实现
利用shell后台运行符&让gedit后台启动,同时记录进程PID后续定向关闭,无需修改过多原有代码:
#include <cstdlib> #include <thread> #include <chrono> int main() { // 后台启动gedit并将PID写入临时文件 system("gedit ./fileName & echo $! > /tmp/gedit_running_pid"); // 休眠10秒 std::this_thread::sleep_for(std::chrono::seconds(10)); // 读取PID终止对应进程,避免误杀其他同名gedit进程 system("kill -15 `cat /tmp/gedit_running_pid` 2>/dev/null"); // 清理临时文件 system("rm -f /tmp/gedit_running_pid"); return 0; }
方案2:POSIX API规范实现(推荐)
直接使用Linux系统调用fork/exec/kill实现,无需依赖临时文件,稳定性更高:
#include <unistd.h> #include <sys/wait.h> #include <thread> #include <chrono> #include <stdexcept> int main() { pid_t gedit_pid = fork(); if (gedit_pid == -1) { throw std::runtime_error("创建子进程失败"); } else if (gedit_pid == 0) { // 子进程执行gedit程序 execlp("gedit", "gedit", "./fileName", nullptr); // exec执行失败才会进入下行逻辑 _exit(EXIT_FAILURE); } else { // 父进程休眠10秒 std::this_thread::sleep_for(std::chrono::seconds(10)); // 发送终止信号,若需要强制杀死可替换为SIGKILL(9) kill(gedit_pid, SIGTERM); // 回收子进程资源,避免产生僵尸进程 waitpid(gedit_pid, nullptr, 0); } return 0; }
注意事项
- 以上方案均仅适用于Linux/Unix系统,Windows环境下需要替换为
CreateProcess、TerminateProcess等WinAPI实现 - 若不需要定向关闭指定gedit进程,也可以直接用
system("pkill gedit")替代PID读取逻辑,但可能误杀用户手动打开的其他gedit窗口 - 优先使用
SIGTERM(15)信号终止进程,会让gedit有机会处理未保存的文件提示,强制杀死才使用SIGKILL(9)
内容的提问来源于stack exchange,提问作者thbake
相关产品推荐
相关产品推荐

