1、进程组
进程组是一个或多进程的集合。通常,它们同一作业相关联,可以接收来自同一终端的各种信号。每个进程组有一个唯一的进程组id。每个进程都可以有一个组长进程。组长进程的标识是,其进程组id等于其进程id。组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在某个进程组中一个进程存在,则该进程组就存在,这与其组长进程是否终止无关。
‘&’ :表示将进程组放在后台执行。
进程: 2931 2932 2933
组长: 2931 ,进程组中的第一个进程
如上图,使用命令 kill -9 2931 杀掉组长进程,进程组还在。
查看进程指令 ps:
(1)a:不仅列当前用户的进程,也列出所有其他用户的进程。
(2)x:不仅列有控制终端的进程,也列出所有无控制终端得进程。
(3)j:列出与作业控制相关的信息。
2、作业
(1) Shell分前后台来控制的不是进程而是作业或者进程组。一个前台作业可以由多个进程组成,一个后台也可以由多个进程组成,Shell可以运行一个前台作业和多个后台作业。
(2)作业与进程组的区别: 如果作业中的某个进程创建了子进程,那么子进程属于当前进程组,但不属于当前作业。
(3)一但作业运行结束,Shell就把自己提到前台(子进程还在,但不属于作业),如果原来的前台进程还存在(子进程还在),子进程自动变为后台进程组。
(4)后台作业可以向前台输出信息,但后台作业不能从前台读取信息。
模拟实现该场景:
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid=fork();
if(pid<0)
{
perror("fork");
return 1;
}
else if(pid==0)
{ //child
while(1)
{
printf("child(%d)# I am running!\n",getpid());
sleep(1);
}
}
else
{ //parent
printf("father(%d) is exit!\n",getpid());
sleep(1);
}
return 0;
}
3、作业控制:
Shell 分前后台来控制的不是进程而是作业或者进程组。一个前台作业可以由多个进程组成,一个后台作业也可以由多个进程组成,Shell可以同时运行一个前台作业和任意多个后台作业。
(1)作业控制常用的指令:
a. 查看后台作业: jobs
b. 将前台作业转到后台状态为stopped : ctrl+z
c. 将后台作业转为前台: fg [作业编号]
d. 将作业放到后台状态为running : bg [作业编号]
(2)
注: cat 查看指令比较特殊,将cat 转为后台其状态只能是stopped,因为cat 是在前台读取信息,而后台作业只能向前台输出信息,不能从前台读取信息,所以cat 转后台状态只能是stopped。因为是stopped状态所以只能使用 kill -9 将其杀死。
4、会话
会话是一个或多个进程的集合。一个会话可以有一个控制终端。这通常是登陆到其上的终端设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下)。建立与控制终端连接的会话首进程被称为控制进程。一个会话中的几个进程组可被分为一个前台进程组以及一个或多个后台进程组。所以一个会话中,应包括控制进程(会话首进程),一个前台进程组和任意后台进程组。
注:有 -bash 表示从网络重登录的; SID是会话ID。