bg 和kill 之间的区别 -CONT

bg 和kill 之间的区别 -CONT

我正在前台运行一个应用程序,然后通过按CTRL+ Z(然后停止)将其置于后台。为了让它重新运行,我运行了命令bg %1(这是它的 JOBSPEC)。

我想为什么不尝试让它运行回来kill -CONT <PID>。所以,我跑去jobs -l获取它的 PID,并将这个 pid 与带有 CONT 信号的kill一起使用。

然而,该节目并没有再次上线!jobs -l尝试用 CONT 杀死后报告它正在运行,但它没有运行(因为它呈灰色)。

我使用该命令查看了应用程序 PID ps,发现两个相同的命令具有不同的 PID(和 status Tl)。

然后我使用相同的东西查看pstree,发现它们都在父进程下。父进程与列出的进程不同,jobs -l因为我放在后台的进程似乎启动了另一个程序。另一个程序似乎创建了子进程。

我注意到的情况总结如下:

  • 使用kill发送 CONT 到父进程使程序运行。

  • 父进程 PID 与 报告的不同jobs -l。换句话说,我应该发送 CONT 信号的进程与我发现使用的进程不同jobs -l

  • 向父进程发送 CONT 不会对子进程应用相同的信号。

  • 使用该命令bg使进程返回运行状态,向其所有子进程的父进程发送 CONT 信号。

我的结论正确吗?如果是这样,那么这意味着使用该命令bg将节省向每个相关进程发送 CONT 的时间。这是正确的吗?

编辑我从命令行调用并放在后台的主要应用程序是git difftool.我正在谈论的另一个应用程序本身创建了新的子项,meld我将其设置为 git 中的比较工具。

答案1

首先,jobs -l没有列出进程,但是进程组(又名工作)。每个进程组都有一个进程领导者,其进程ID(pid)等于其进程组ID(pgid)。

为了向进程组中的所有进程发送信号,而不仅仅是向其领导者发送信号,您应该kill使用 pgid 的负数进行调用。 Kill(2) 联机帮助页对此进行了描述:

如果pid小于-1,则将sig发送到进程组中ID为-pid的每个进程。

在 shell 中也有同样的作用:

$ sh -c 'while echo -n 1; do sleep 1; done'
111^Z
[1]+  Stopped                 sh -c 'while echo -n 1; do sleep 1; done'
$ jobs -l
[1]+ 11046 Stopped                 sh -c 'while echo -n 1; do sleep 1; done'
$ kill -CONT 11046
   <nothing>
$ kill -CONT -11046
$ 11111111...

现在,得出你的结论:

使用kill 向父进程发送CONT 使程序运行。

正确的

父进程 PID 与 jobs -l 报告的 PID 不同。换句话说,我应该发送 CONT 信号的进程与我使用 jobs -l 找到的进程不同。

错了,是同一个pid,也和它的pgid一样。

向父进程发送 CONT 不会对子进程应用相同的信号。

正确的

使用命令 bg 使进程返回运行状态,向父进程及其所有子进程发送 CONT 信号。

是的,但前提是父进程和子进程都在同一个进程组中。另外,它不会依次为每个进程调用kill(2),它只是使用pgid(=进程组领导者的pid)的负数调用一次,并依赖内核将信号路由到所有进程在那个组里。

答案2

我在这里没有看到这种行为。

  • 这是我的示例代码,在命令行中逐字输入:

    bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
    
  • 一旦收到消息This is child xx,请点击CtrlZ暂停该进程。

  • 再等待 7 秒以确认它确实已暂停

  • 现在jobs -l列出进程领导者(父PID)。实际上,我们可以使用职位编号,在本例中%1

  • 在后台继续该过程kill -CONT %1

我看到孩子继续然后退出,让家长完成。

这是完整的运行结果(包括>$shell提示)

>$ bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
This is parent 2004
This is child 10696

[1]+  Stopped                 bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
>$ jobs -l
[1]+  2004 Stopped                 bash -c 'echo This is parent $$; sleep 7; bash -c "echo This is child \$$; sleep 7; echo Child done"; echo This is parent $$ again; sleep 7'
>$ kill -CONT %1
>$ Child done
This is parent 2004 again

如果您想进一步尝试自动测试工具,您可以使用发送与键盘上kill -TSTP ...生成的信号相同的信号。CtrlZ

相关内容