【Linux】进程组、作业、回话、守护进程的基本概念!!

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Doctor_xiong/article/details/79953509

进程组
每一个进程在创建的时候就有自己的进程ID,同时也有自己的ID(PGID)。一个进程组,可以含有一个或者多个进程,进程组也有自己的ID,通常是进程组里面第一个进程的ID。
进程组的特点:

  • 每一个进程组有一个组长进程,进程组长的ID等于进程组ID
  • 进程组长可以创建进程组、创建进程组里面的进程
  • 只要进程组里面含有进程,那么进程组就存在,这与进程组长的存在没有关系
  • 进程组里面的最后一个进程可以终止,也可以转移到其他的进程组
 #include <unistd.h>
 int setpgid(pid_t pid, pid_t pgid);
 pid_t getpgid(pid_t pid);
                             成功返回0,失败返回-1

getpgid:用来获取pid进程所在进程组的ID
setpgid:用来创建或将进程加入到指定的进程组
这里写图片描述
注:这里的3个sleep构成进程组,进程组长为3502。

会话
会话是由一个或者多个进程组组成的集合。
进程调用setsid函数用来创建一个新会话:

#include <unistd.h>
pid_t setsid(void);

注:调用该函数的进程不能够是进程组的组长(防止会话ID重复)。通常是先进行fork之后再调用setsid函数创建会话。

当调用setsid函数之后发生的事情:

  1. 调用setsid函数的进程成为新进程组的组长
  2. 该进程成为新会话的首进程,此时,该进程是新会话中的唯一进程
  3. 该进程没有控制终端
#include <unistd.h>
pid_t getsid(pid_t pid);

getsid:获得当前进程的会话ID。如果调用的进程不属于调用者所在的会话,那么调用的进程不能获得该会话ID。

作业控制
Shell的工作方式分为前台和后台,Shell控制的不是进程而是作业,在前台工作的作业,一次只能有一个,但是在后台工作的作业一次可以是很多个。
作业控制需要以下三种形式的支持:

  1. 支持控制作业的Shell
  2. 内核的终端驱动程序必须支持作业控制
  3. 内核必须提供对某些作业控制信号的支持

1、当我们在前台可以使用键盘发出信号使前台的作业终止,但是并不能使后台的作业发生终止。实际上有三个字符可使终端驱动产生信号:

  • 中断字符产生SIGINT
  • 退出字符产生SIGQUIT
  • 挂起字符产生SIGTSTP

2、只有前台作业可以接受终端的输入,如果后台作业试图读取终端的输入,那么终端驱动就会给后台作业发送SIGTTIN(15号)信号,同时停止该后台作业。

例如:将cat放在后台执行
这里写图片描述

当后台的作业处于stopped状态的时候,使用kill 命令发送信号的时候没有作用(除开9号信号),因为在发送信号之后再内核态到用户态的时候才会去处理信号,但是处于stopped状态的作业,只会停止不动,不会调用系统调用。

守护进程

守护进程也被称为精灵进程,本质是孤儿进程。是一种在后台执行的特殊进程。
在linux里面,其他的进程都会在运行结束或者系统注销之后终止,但是守护进程不受用户注销的影响,只要系统不关机,那么守护进程就会一直运行。

创建一个守护进程

  • 创建新的会话(使用setsid();),并让当前进程称为Session Leader
  • 用当前进程创建新的进程组,当前进程为进程组的组长。

也可以调用daemon函数创建守护进程

#include <unistd.h>
int daemon(int nochdir, int noclose);

nochdir:0表示更改当前工作目录,非0表示不更改
noclose:0表示关闭文件描述符,非0表示不关闭

注:守护进程之所以和用户注销没有关系,是因为用户注销销毁的是一个会话,而守护进程独自成会话、进程组,所以可以不受用户注销影响。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页