C语言 向调用 exec() 的分支进程发送信号



我有一个简单的 C 程序,它分叉一个进程并调用 exec 来运行如下命令:

#include<stdio.h>
#include<signal.h>
#include<unistd.h>
#include<sys/types.h>
int fork_process(int sleep_interval) {
   char cmd[30];
   pid_t pid = fork();       
   if (pid > 0) {
       return pid;
   }
   else if (pid < 0) {
        printf("At parent. Couldn't create a child process!n");
        return pid;
   }
   else { 
        sprintf(cmd, "sleep %d; %s", sleep_interval, "gzip a > a.gz");
        execlp("sh", "sh", "-c", cmd, (char *) 0);
   }
}
int main () {
   pid_t pid = fork_process(400);
   sleep (10);
   kill(pid, SIGTERM);
   return 1;
}

当我运行这个程序时,我注意到sh内部分叉一个进程来运行sleep 400

$ps x
  1428 pts/80   S+     0:00 ./kill_prog
  1429 pts/80   S+      0:00 sh -c sleep 400; gzip a > a.gz
  1430 pts/80   S+      0:00 sleep 400

现在,当SIGTERM信号在程序中通过其 pid 发送到子进程(此处1429)时,我注意到子进程终止,但执行sleep 400的进程没有终止(pid 1430)。换句话说,执行sleep 400的进程在完成之前会变成僵尸。

如何发送终止信号,以便将信号传播到子进程中分叉的进程?我尝试在kill中使用进程组 ID 作为kill(-1*pid, SIGTERM)但无济于事。

我终于找到了上述问题的解决方法。这是两个小变化的问题。

我在分叉子项后在父级中添加执行此操作:

pid_t pid = fork();   
if (pid > 0) {
   // Make child process the leader of its own process group. This allows
   // signals to also be delivered to processes forked by the child process.
   setpgid(childpid, 0); 
   return pid;
}

最后,将信号发送到整个流程组:

// Send signal to process group of child which is denoted by -ve value of child pid.
// This is done to ensure delivery of signal to processes forked within the child. 
kill((-1*pid), SIGTERM);

非常简单:只需在流程中添加一个 SIGTERM 信号处理程序:

  • http://rackerhacker.com/2010/03/18/sigterm-vs-sigkill/

最新更新