背景,僵尸,守护程序和不带ctty的这些概念是否连接在一起?


8

这些过程的概念是如何关联在一起- ,,background 和?zombiedaemonwithout controlling terminal

我觉得它们之间有某种距离,特别是通过的概念controlling terminal,但是我仍然没有太多信息可以讲述一个故事,例如是否需要给一个孩子讲一些有关Linux的文章而又不撒谎。

更新#1:例如(我不知道这是不是真的)

  • background-- zombie前台进程无法成为zombie,因为zombie是没有父进程的后台进程
  • daemon- without ctty-所有daemons无运行ctty,但不是所有的过程,而不cttydaemons
  • background-- 可以检索到daemona background process以再次交互式运行,daemon is not
  • zombie- without ctty- zombie如果有无所谓ctty连接到它或不
  • background- without ctty- processes发送到后台,而他们有ctty,如果成为守护进程或模具ctty是从他们采取

前台进程当然可以是僵尸,尽管通常在任何可观的时间段内都不是僵尸-Shell(或其他程序)在前台运行子进程的通常方法是fork()关闭自己的副本,并exec()在该副本中使用将其替换为您要运行的内容,并wait()在程序的原始实例(而不是运行的副本exec())中使用。在孩子退出与wait()获得退出状态之间的非常短的时间内(将其从过程表中删除并将其返回给调用方),您就有了一个僵尸。
Charles Duffy

@CharlesDuffy是否可以将父级发送到后台,而让孩子在前台运行?
anatoly techtonik

典型的作业控制中,shell甚至根本不知道孙子与它的直接子是分开的。它只是在等待孩子退出,如果孩子正在等待孙子退出,那是孩子的事。也就是说-从产生父对象的外壳的角度来看,它仅处理一个单元。
Charles Duffy

Answers:


10

简而言之,加上链接。

僵尸

已经退出/终止但其父级尚未确认终止的进程(使用wait()系统调用)。死进程保留在进程表中,以便可以通知其父进程其子进程退出的子进程及其退出状态。通常,派生孩子的程序也会在退出时读取退出状态,因此只有当父母停下车或越野车时,您才会看到僵尸。

看到:

控制终端,会话,前景,背景

这些与终端上运行的Shell上下文中的作业控制有关。用户登录,启动会话,绑定到终端(控制终端)并启动外壳程序。然后,shell运行进程,并根据用户期望将它们发送到前台和后台(&在启动进程时使用^Z,使用fg和停止进程bg)。如果从终端读取或写入,则后台进程将停止;如果^C在终端上被击中,则前台中的进程会收到中断信号。(处理这些信号的是内核的终端驱动程序,外壳程序控制将哪个进程(组)发送到前台或后台。

看到:

守护程序

作为守护程序运行的进程通常不应绑定到任何特定的终端(或登录会话或外壳程序)。它不应该具有控制终端,因此如果终端关闭,它也不会接收信号,并且通常也不希望它在终端上执行I / O。从命令行启动守护程序需要断开与终端的所有联系,即开始新的会话(在上述作业控制的意义上)以摆脱控制终端,并关闭终端的文件句柄。当然init,在登录会话之外从,systemd或类似内容开始的事情并没有这些联系。

由于守护程序没有控制终端,因此它不受作业控制,并且在作业控制意义上处于“前景”或“背景”也不适用。另外,守护程序通常会init在退出时重新与其父级进行清理,因此您通常不会将其视为僵尸。

看到:


4

僵尸与其他人并没有真正的联系。它只是一个已终止的进程,但其父进程尚未读取具有waitpid()或类似状态的退出状态。除非流程有错误或已停止,否则您不应看到这些内容。

守护程序是一个程序,运行没有控制终端。通常,当您运行该程序时,它fork()s本身就会退出,并且父程序退出,因此shell会认为命令已完成,并且子进程会从终端分离,并退出登录会话。由于其父进程已退出,因此其父进程ID变为1,这通常是该init程序,或者最近是systemd。此过程可确保在其子死后为其收割,这样您就不会因僵尸而超支。

进程可以与控制终端相关联,该终端通常是从那里获取输入并将其输出发送到的地方。终端还可以向与其连接的进程发送信号,并将进程组标识为前台组。允许前台组中的进程从终端读取输入,并在按Ctrl-C和Ctrl-Z时向其发送SIGINT和SIGSUSP信号。尝试从终端读取的不在前台组中的任何进程都将被SIGTSTP挂起。

Shell为您要求其运行的每个管道命令创建不同的进程组,并转移哪个是前台组以在前台和后台之间移动作业。运行命令时,通常外壳程序会创建一个新的进程组,并将该组作为前台组。如果给它加一个后缀,&那么外壳程序仅将前景组留在原处,因此新组位于背景中。按下Ctrl-Z会将SIGSUSP发送到前台组,这将导致大多数命令挂起,但是Shell而不是挂起,而是将活动的前台组改回了自己,以便可以提示您输入新命令。

bg命令将SIGCONT发送到进程组,以便在被SIGSUSP挂起后可以在后台继续运行。 fg改变前台组已在后台运行的现有组之一,将其置于前台。


4

好的,这是我的解释,着重介绍了这些类型的流程之间的差异(简短但内容丰富):

  • zombie-刚刚退出(完成执行)但在进程表中仍具有条目的进程。注意僵尸进程仍然有一个父级,通常存在的全部目的是让该父进程知道子进程执行的结果(退出代码等)。
  • disowned process(无控制终端)- disown由用户明确创建或设计为与父流程树分离的流程。即使父进程将完成执行,它仍将运行。例如,用户ssh进入远程计算机,启动了类似Web服务器的程序,然后disown在其上运行并退出了ssh会话。该进程仍将继续运行,因为它不再是父进程树的一部分。也可以使用取消运行进程nohup
  • background process-在后台运行-不会将输出拆分到用户的tty。要么最终运行,要么&通过设计将自己分叉到背景中。将进程发送到后台的另一个选项是启动它,然后按ctrl+z。但是,当父进程将终止时,在后台运行的子进程也将终止(@psusi 注意 -先验事实仅适用于由用户从终端启动的进程;否则,子进程将成为“孤儿”并获得init进程(pid 1)作为父进程)。
    • daemon-非常类似于后台流程。也可以在后台运行,但是很可能是隐式分叉的(通过设计)。通常,它安静地坐在后台,等待某些事件甚至发生,然后才进行实际工作(传入连接等)。实际上,取决于守护程序的设计,守护程序既可以不存在(很有可能),也可以不进行后台处理。

希望这种解释将有助于区分这些类型的过程。


真好 进程表属于父级吗?那么僵尸在没有主人的情况下会死吗?
anatoly techtonik

表不是正确的词。这是一个过程tree。是的,可以肯定,父级在子级终止后并不一定要终止(但是如果它在等待子级完成某种事物的处理,则可以这样做)。但是如果父母终止了,孩子肯定会终止。您可以top从终端运行,然后按shift-v狂放地查看流程树。
ddnomad

1
父母终止并不杀死其子女。孤儿的父进程ID更改为init(1)。
psusi

@psusi你是对的,我忘了只有在终端启动的进程才是这样。我会改正我的答案。
ddnomad

我只是删除“它将很快从表中消失”一句。它暗示它会在一段时间后自动消失,但事实并非如此。“消失”是一个非常具体的事件。
AnoE
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.