【发布时间】:2020-04-26 04:49:30
【问题描述】:
我正在用 C 编写一个 shell,我正在尝试添加信号处理。在 shell 中,调用 fork() 并且子进程执行 shell 命令。子进程被放入它自己的进程组中。这样,如果在子进程处于前台时按下 Ctrl-C,它将关闭共享相同进程组 ID 的所有进程。 shell 按预期执行命令。
问题在于信号。例如,当我执行“sleep 5”,然后按 Ctrl-C 进行 SIGINT 时,“shell>”提示符按预期出现,但进程仍在后台运行。如果我在按下 Ctrl-C 后快速运行“ps”,睡眠呼叫仍然存在。然后在 5 秒后,我再次运行“ps”,它就消失了。当我按下 Ctrl-Z (SIGTSTP) 时也会发生同样的事情。使用 SIGTSTP,进程会按预期进入后台,但不会暂停执行。它会一直运行直到完成。
为什么这些进程会像这样被发送到后台并继续运行? 这是我的代码的要点...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int status;
void sig_handler_parent()
{
printf("\n");
}
void sig_handler_sigchild(int signum)
{
waitpid(-1, &status, WNOHANG);
}
int main()
{
signal(SIGCHLD, sig_handler_sigchild);
signal(SIGINT, sig_handler_parent);
signal(SIGQUIT, sig_handler_parent);
signal(SIGTERM, sig_handler_parent);
signal(SIGCONT, sig_handler_parent);
signal(SIGTSTP, sig_handler_parent);
while (1)
{
printf("shell> ");
// GET COMMAND INPUT HERE
pid = fork();
if (pid == 0)
{
setpgid(getpid(), getpid());
execvp(cmd[0], cmd);
printf("%s: unknown command\n", cmd[0]);
exit(1);
}
else
waitpid(0, &status, WUNTRACED);
}
return 0;
}
附言我已经尝试在执行命令之前将所有信号处理程序设置为 SIG_DFL。
【问题讨论】:
-
如果子进程在自己的进程组中,它不会收到发往父进程组的信号,对吗?