在Linux中,当一个子进程终止而它的父进程还没有等待它时,它就变成了一个僵尸进程。子程序的退出代码存储在pid描述符中。
如果一个SIGKILL被发送给孩子,就不应该有任何效果。
这是否意味着退出代码不会被SIGKILL修改,或者退出代码是否会被修改以指示子程序由于接收到SIGKILL而退出?
发布于 2016-01-22 09:56:23
要回答这个问题,您必须了解信号是如何发送到进程的,以及进程在内核中是如何存在的。
每个进程都表示为内核内部的task_struct (定义在sched.h头文件中并开始于这里)。该结构保存有关进程的信息;例如pid。重要信息在存储相关信号的第1566行中。只有当信号被发送到进程时,才会设置此选项。
死进程或僵尸进程仍然有一个task_struct**.**结构,直到父进程(自然的或采用的)在接收到SIGCHLD后调用wait()来获取其子进程。当一个信号被发送时,signal_struct被设置。在这种情况下,信号是否可捕捉并不重要。
每次进程运行时都会对信号进行评估。或者准确地说,在这个过程开始之前。然后,该进程处于TASK_RUNNING状态。内核运行schedule()例程,根据其调度算法确定下一个运行过程。假设此进程是下一个正在运行的进程,则计算signal_struct的值,无论是否存在要处理的等待信号。如果手动定义了信号处理程序(通过signal()或sigaction()),则执行已注册的函数,如果没有执行信号的默认动作。默认操作取决于所发送的信号。
例如,SIGSTOP信号的默认处理程序将将当前进程的状态更改为TASK_STOPPED,然后运行schedule()以选择要运行的新进程。注意,SIGSTOP是不可捕捉的(如SIGKILL),因此不可能注册手动信号处理程序。在不可捕捉的信号情况下,将始终执行默认操作。
调度程序将永远不会将已停止或死掉的进程确定为再次处于TASK_RUNNING状态。因此,内核将永远不会运行相应信号的信号处理程序(默认或定义),不管是哪个信号。因此,再也不会设置exit_signal了。通过在进程的signal_struct中设置task_struct将信号“传递”到进程,但不会发生其他任何事情,因为该进程将永远不会再次运行。没有要运行的代码,剩下的所有进程都是进程结构。
但是,如果父进程通过wait()获取其子进程,则它收到的退出代码是进程“最初”死亡时的退出代码。是否有等待处理的信号并不重要。
https://unix.stackexchange.com/questions/256926
复制相似问题