【问题标题】:Fork, execlp and kill. Zombie process分叉、执行和杀死。僵尸进程
【发布时间】:2017-05-26 06:44:03
【问题描述】:

我有一个使用 fork 和 execlp 执行另一个进程(bash 脚本)的 c 程序。当我想杀死这个进程时,它会进入僵尸状态。这是为什么呢??

创建一个进程:

    switch (PID_BackUp= fork())
    {
      case -1:
          perror("fork");
          printf("An error has occurred launching backup.sh script!\n");
          break;

      case 0:
          execlp("/usr/local/bin/backup.sh", "/usr/local/bin/backup.sh", NULL, NULL, NULL);
          break;

      default:
          printf("backup.sh script launched correctly! PID: %d\n", PID_BackUp);
          break;
    }

杀死一个进程:

    if(kill(PID_BackUp,SIGKILL)==-1)
        fprintf(stderr, "No se ha podido matar el programa: %d\n", PID_BackUp);
    else
        printf("\nProceso con identificador %d, se ha abortado\n", PID_BackUp);

所以此时进程进入僵尸状态。我做错了什么?

【问题讨论】:

    标签: linux fork kill zombie-process


    【解决方案1】:

    您应该调用 waitpid(2) 或其他一些等待系统调用 (wait4(2)...) 以避免出现 zombie processes。顺便说一句,您还可以处理SIGCHLD 信号,以便在子进程终止(或更改状态)时收到通知。

    一般来说,你最好先kill(2) 一个带有SIGTERM 的进程(然后才使用SIGKILL),因为该进程-您的backup.sh 脚本-可以正确处理(使用trap 内置在shell 脚本)信号(但SIGKILL 无法被捕获,并且备份可能会在磁盘上留下杂乱或无用的文件)。另见signal(7) & signal-safety(7)

    阅读Advanced Linux Programming(我们无法用几章几章的几章来解释这本免费提供的书所教的内容)。

    顺便说一句,当系统调用失败时,最好在消息中使用perror(3)strerror(errno)

    【讨论】:

    • 那么,使用fork的进程是否应该等待子进程(waitpid)?我在我的通用程序(嵌入式平台)中使用 fork,所以我不能等待子进程(我必须创建一个特定的线程)
    • 是的,在某些时候您应该waitwaitpid。但是,请阅读更多关于 SIGCHLD
    猜你喜欢
    • 2013-06-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2014-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2011-04-29
    相关资源
    最近更新 更多