当父进程等待子进程终止时,子进程如何杀死父进程?

3
我不理解下面的代码:
pid_t pid;
int counter = 0;
void handler1(int sig) {
  counter++;
  printf("counter = %d\n", counter);
  fflush(stdout);
  kill(pid, SIGUSR1);
}
void handler2(int sig) {
  counter += 3;
  printf("counter = %d\n", counter);
  exit(0);
}
int main() {
  signal(SIGUSR1, handler1);
  if ((pid = fork()) == 0) {
    signal(SIGUSR1, handler2);
    kill(getppid(), SIGUSR1);
    while (1) {
    };
  } else {
    pid_t p;
    int status;
    if ((p = wait(&status)) > 0) {
      counter += 2;
      printf("counter = %d\n", counter);
    }
  }
}

孩子进程如何在父进程等待其子进程终止时实际上杀死父进程?

使用情境:父进程分叉产生子进程。子进程在启动时首先读取配置等信息,并且只有在成功启动后才向父进程发送SIGUSR1信号。在此之前,如果子进程在启动过程中失败(如在wait()中),父进程会收到通知;而在处理完SIGUSR1信号后,父进程会终止并假定子进程已经启动成功。 - Jonas Schäfer
1个回答

4
首先需要注意的是,kill()系统调用的名称有些不准确,它是一个通用的向进程发送信号的函数。杀死目标进程只是可能的结果之一。
更普遍地说,信号处理是一种中断机制。许多库函数,包括wait(),都可以被接收到的信号中断。如果已经注册了该信号的处理程序,则控制权将传递给它,否则执行默认操作。之后,被中断的函数返回,通过其返回代码和/或设置errno来指示错误。
此外,您自己的代码也可能会因接收到信号而被中断。只要效果不是终止进程,如果信号处理程序正常退出,则执行将在离开的点上恢复,否则在处理程序通过调用longjmp()退出时在其他某个点上恢复。
另外,信号传递是由内核处理的异步机制。进程可能被阻塞或以其他方式占用,仍然可以接收信号;实际上,这就是它们的重要部分。每个进程都有一个等待处理的挂起信号队列;对于大多数进程,此队列几乎始终为空,但除非显式地阻止信号,否则进程永远不能安全地假定它不会收到任何信号(并且某些信号无论如何都不能被阻止)。
在您的特定代码中,主进程首先将function1()设置为其处理程序,以处理信号USR1。然后它进行分叉,并将函数function2()设置为处理程序,以处理信号USR1(从而不影响父进程),向父进程发送信号USR1,并进入一个无限循环。
同时,父进程启动wait()等待其子进程。这将被接收到的信号中断。等待将在接收到信号并注册处理程序运行后结束,wait()返回-1并设置errnoEINTR。处理程序执行的操作之一是向子进程发送SIGUSR1信号。
接收到信号后,子进程的正常执行流程将被中断以运行其处理程序function2()。这将更新子进程的变量counter副本,打印其值,然后exit()
最终结果:
主进程打印

counter = 1

然后退出。子进程打印

counter = 3

然后退出。

那么你的意思是即使使用kill函数也无法成功杀死父进程,它仍然会发送信号。 - Makara
@Jonh,在handler1中的kill函数不会将信号发送回触发信号函数的子进程吗?在该处理程序中,程序调用exit函数终止子进程,所以我认为这就是它不在无限循环中的原因。你怎么看? - Makara
@Jonh,我尝试在我的电脑上运行这段代码,结果出现了不同的情况。它完全终止了。我认为这里的exit函数可能会完全终止子进程,是吗?很抱歉再问一下,但我有点困惑。 - Makara
@Jonh,exit函数是终止整个进程,是指调用exit函数的那个进程。它不仅仅是通知系统该函数已经完成了,对吗? - Makara
@Makara,是的,exit()函数会导致调用它的进程终止。然而,它对其他进程没有(直接)影响。特别是,子进程是独立于父进程的,所以当子进程退出时,不会影响父进程。(从技术上讲,当子进程因任何原因终止时,它的父进程会收到一个SIGCHLD信号。这也会在程序通过从main()返回退出时发生,而且默认情况下对该信号的处理是忽略它)。 - John Bollinger
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接