求助:Ubuntu下用C语言实现按Ctrl+C关闭Vim的解决方案
问题分析与解决方案
原代码核心问题
system("vim abcd.txt")会阻塞线程直到Vim退出,导致线程内的signal(SIGINT, on_sigint1)从未执行,信号处理逻辑完全失效。- 按下
Ctrl+C时,SIGINT信号会发送给前台进程组的所有进程,Vim默认会捕获该信号并回到命令模式而非退出,你的killall逻辑即便执行也存在误杀其他Vim进程的风险。 - 全局变量
loggg无同步机制,多线程访问存在竞态问题。
修正后的实现方案
改用fork()创建子进程启动Vim,获取Vim的PID后,在收到SIGINT时精准终止目标进程,同时避免线程阻塞问题:
// IT007 Operating System // <Your name>, <your Student ID> // File: example_system.c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> #include <sys/wait.h> pid_t vim_pid = -1; void handle_sigint(int sig) { if (vim_pid != -1) { // 向目标Vim进程发送终止信号 kill(vim_pid, SIGTERM); printf("\nVim已关闭,程序即将退出\n"); } exit(EXIT_SUCCESS); } int main() { printf("Hello IT007! 即将打开Vim编辑器 ^_^\n"); // 注册SIGINT信号处理函数 signal(SIGINT, handle_sigint); // 创建子进程启动Vim vim_pid = fork(); if (vim_pid == -1) { perror("fork失败"); exit(EXIT_FAILURE); } else if (vim_pid == 0) { // 子进程执行Vim execlp("vim", "vim", "abcd.txt", NULL); perror("启动Vim失败"); exit(EXIT_FAILURE); } else { // 父进程等待Vim进程结束 wait(NULL); printf("Vim已正常退出\n"); } return 0; }
关键改进点
- 用
fork()+execlp()替代system(),避免线程阻塞,同时获取Vim的PID,实现精准终止,不会误杀其他Vim实例。 - 在主进程统一处理SIGINT信号,收到信号后直接终止Vim并退出程序,逻辑简洁高效。
- 移除不必要的线程和全局变量,避免多线程竞态问题。
编译运行命令
gcc example_system.c -o vim_controller ./vim_controller
按下Ctrl+C时,Vim会被立即终止,程序同步退出。
内容的提问来源于stack exchange,提问作者Duy Phạm
相关产品推荐
相关产品推荐

