为什么我的子进程的PGID不是父进程的PID?


13

因此,我到处都读到该命令应终止父进程的所有子进程:

kill -- -$$

在kill命令中使用负ID引用了一个PGID,从示例中我已经看到,子进程的PGID似乎应该是父进程的PID,但在我的系统上不是这样。

在我的系统上,子代的PGID与父脚本的PGID相同,后者实际上是bash。

这里发生了什么?示例是错误的还是我的系统设置不同?

我需要实现的是在不终止父进程的情况下终止子进程,因此我不想向父进程所在的PGID发送终止信号。

Answers:


11

我认为您的意思是PGID,代表进程组ID

派生一个进程时,它从其父级继承其PGID。当流程成为流程组负责人时,PGID更改,然后从其PID复制其PGID。从那时起,新的子进程将产生,其子代继承该PGID(除非他们启动自己的新进程组)。

在具有作业控制的外壳中(例如,大多数交互式外壳),每个作业都放在其自己的进程组中。如果运行Shell脚本,则运行该脚本的Shell进程将成为组领导,而PGID将等于其PID。

在没有作业控制的shell中(例如,大多数用于运行脚本的shell),命令在shell的进程组中运行。

该语法会kill -- -N杀死PGID = N的组中的所有进程。您不能将其与任意PID一起使用,只能与进程组负责人的PID一起使用,因为这就是PGID。本质上就是外壳的

kill %jobid

语法有效-它在内部转换%jobid为作业的PGID,并将信号发送到该PGID。

没有简单的方法可以从另一个Shell脚本在其自己的进程组中运行脚本。不过,请参阅如何设置外壳程序脚本的进程组以获取一些建议。


您是说带或不带作业控制的外壳会发生相同的事情吗?
TCZ8 2014年

1
不能。具有作业控制的外壳程序会为每个作业启动一个新的进程组。没有作业控制的外壳程序不会为每个作业启动新的进程组,而是在自己的进程组中运行它们。
Barmar 2014年

哇..我第一次没看清楚。所以我想我想要打开工作控制?这样可以确保子代的PGID与父脚本的PID匹配吗?还是每个孩子都有自己独特的PGID?
TCZ8 2014年

我在网上找到了一些有关工作控制的文档,这很麻烦。感谢您对Barmar的帮助。
TCZ8 2014年

1
通过作业控制,每个孩子都有自己的PGID。没有作业控制,它们将继承父级的PGID。但父母可能已经继承了其所属的呼叫群组从它的父,如果它不是一个进程组组长。
Barmar 2014年
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.