我有一个简单的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
此处)发送到子进程时,我注意到子进程终止但不是正在执行的进程{{1} }(pid sleep 400
)。换句话说,执行1430
的过程在完成之前变为僵尸。
如何发送一个kill信号,使信号传播到子进程中分叉的进程?我尝试将sleep 400
中的进程组ID用作kill
,但无济于事。
答案 0 :(得分:3)
我终于找到了解决上述问题的方法。这是两个小小的变化。
我在分娩后添加到父母那里做这件事:
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);
答案 1 :(得分:0)
非常简单:只需向进程添加SIGTERM信号处理程序: