linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact

linux:进程组作业会话—conceptdistinctioncontact

linux:进程组&作业&会话—concept&distinction&contact

Foreword

本文介绍了linux中进程组、作业、会话的基本概念,并分别对其进行代码举例分析。

主要内容有:

3者基本概念

3者间的区别与联系

tips:全文阅读需要**5min**

Concept

NO.1 进程组(Process Group)

事实上,每个进程除了有一个进程ID(pid)之外,还属于一个进程组。

进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID(pgid)。

此外,关于组长进程,还有以下几点:

* 每个进程组都有一个组长进程。且其pid就是该进程组的ID,故进程组中所有子进程的pgid都是该组组长进程的pid

* 组长进程可以创建一个进程组,创建该组中的进程,然后终止。

* 只要某个进程组中有一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。

* 每个进程组都有一个组长进程。且其pid就是该进程组的ID,故进程组中所有子进程的pgid都是该组组长进程的pid

以上就是进程组的所有基本概念,接下来对这些结论进行验证:

写一个while死循环程序test.c,并令与另两个进程一起创建一个有3个后台进程的进程组:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第1张图片

用ps命令查看可以看到:

有三个pid分别为27339、27340、27341的后台进程共属同一进程组,且进程组组长就是该进程组中的第一个进程。且组长进程的pid就是进程组id:27339

3个后台进程父进程均为bash,所以是兄弟关系。因此可以通过管道通信。

bash的pid与pgid相同,所以bash本身是一个独立的进程组。

NO.2 作业(Job)

作业与进程组的概念类似,一个作业也是由多个进程组成的。一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以同时运行一个前台作业和任意多个后台作业。

进程组用pgid来标识,作业是用作业号来标识的:

f9a2d269e07112f981a671518f13ab87.png

上图中,建立了2个后台作业,前边的1和2就是其对应的作业编号。

除此之外,我们还可以用jobs命令查看所有后台作业:

8262d143345b5b8baf6804b48b4eedca.png

NO.3 会话(Session)

会话(Session)是一个或多个进程组的集合。一个会话有一个控制终端。这通常是登陆到其上的终端设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下)。

与进程组相似,每一个会话也有其对应的会话ID:SID

一个会话应该包括:

1. 控制进程:建立与控制终端连接的会话首进程。

2. 一个前台进程组和任意后台进程组。

接下来我们通过例子来深入理解会话的概念:

Step1:创建2个后台进程组和1个前台进程组

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第2张图片

Step2:打开另一个tenminal终端查看SID:会话ID

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第3张图片

在SID栏可以看到系统中有2个会话,ID分别为5709和27878。其中bash自成进程组和会话,并且是会话的首进程。所以控制进程一般都是bash。

因为我们打开了另一个终端,所以会出现两个会话。如果再打开一个终端,会话个数又会增加到3个:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第4张图片

其中,TTY对应的pts正对应着3个终端。

因此我们可以总结:每打开一个终端就是新建一个会话的过程,关闭一个终端就是终止一个会话

上例中各进程、进程组、Session的关系如下图所示:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第5张图片

distinction&contact

在上边的三个概念中,只有进程组和作业比较难以区分,所以我们只关注进程组和作业的区别。

如果作业中的某个进程又创建了子进程,则该子进程不属于作业。 一旦作业运行结束,Shell就把自己提到前台,如果原来的前台进程还存在(如果这个子进程还没终止),它?动变为后台进程组。这就是他们的区别。

简单来说就是:进程组中某进程创建出的子进程属于进程组,不属于作业。

接下来我们证明一下这个现象:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第6张图片

上面的代码模拟了这个现象,先fork出子进程,然后父进程退出。

运行代码:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第7张图片

按照上边的说法,程序的运行结果应当是父进程退出后,作业运行结束,shell在前台运行。子进程变为后台进程才对。

然而上边的运行结果中作业运行结束后子进程还是前台运行,难道错了吗?

用命令查看一下:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第8张图片

结果表明子进程状态从S+变为S,确实变成了后台进程。

其实,上边的结果并没有错,不信你可以输一下:

linux 会话 进程组,linux:进程组作业会话—conceptdistinctioncontact_第9张图片

可以看到,shell命令依旧是可以运行的,只不过输入的命令被后台进程的输出结果冲散了而已。。。所以,结果是正确的。

这个例子中,子进程在前台运行。刚开始根本停不下来。父进程退出后,前台作业也相继退出。由于子进程不属于作业。而且shell只能有一个前台作业和多个后台作业,所以bash把自己提到前台,子进程只能被提到后台运行。

以上就是作业和进程组的区别,可以看到。只要不涉及子进程,他们其实并没有什么分别。所以,一般情况下,可以把作业当成进程组,进程组当成作业。不做明显区别。

The End

关于作业,其实还有一个重要的概念,就是作业控制。博主也会在后续博文中加以介绍。敬请期待哟~

linux:进程组作业会话—conceptdistinctioncontact相关教程

你可能感兴趣的:(linux,会话,进程组)