You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:Ubuntu下用C语言实现按Ctrl+C关闭Vim的解决方案

问题分析与解决方案

原代码核心问题

  1. system("vim abcd.txt")会阻塞线程直到Vim退出,导致线程内的signal(SIGINT, on_sigint1)从未执行,信号处理逻辑完全失效。
  2. 按下Ctrl+C时,SIGINT信号会发送给前台进程组的所有进程,Vim默认会捕获该信号并回到命令模式而非退出,你的killall逻辑即便执行也存在误杀其他Vim进程的风险。
  3. 全局变量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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 20:00:09