搞懂进程组、会话、控制终端关系,才能明白守护进程干嘛的?

一口Linux 2020-10-19 00:00

守护进程

概念:

守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程。周期性的执行某种任务或等待处理某些发生的事件。

Linux系统有很多守护进程,大多数服务都是用守护进程实现的。比如:像我们的tftp,samba,nfs等相关服务。

UNIX的守护进程一般都命名为*d的形式,如httpd,telnetd等等。

生命周期:

守护进程会长时间运行,常常在系统启动时就开始运行,直到系统关闭时才终止。

守护进程不依赖于终端

从终端开始运行的进程都会依附于这个终端,这个终端称为这些进程的控制终端。当控制终端被关闭时,相应的进程都会被自动关闭。咱们平常写进程时,一个死循环程序,咱们不知道有ctrl+c的时候,怎么关闭它呀,是不是关闭终端呀。也就是说关闭终端的同时也关闭了我们的程序,但是对于守护进程来说,其生命周期守护需要突破这种限制,它从开始运行,直到整个系统关闭才会退出,所以守护进程不能依赖于终端。

查看守护进程

ps axj

a: 显示所有 

x:显示没有控制终端的进程 

j:显示与作业有关的信息(显示的列):会话期ID(SID),进程组ID(PGID),控制终端(TT),终端进程组ID(TRGID)

• 所有的守护进程都是以超级用户启动的(UID为0);

• 没有控制终端(TTY为?);

• 终端进程组ID为-1(TPGID表示终端进程组ID,该值表示与控制终端相关的前台进程组,如果未和任何终端相关,其值为-1;

• 所有的守护进程的父进程:

历史上,Linux 的启动一直采用init进程;下面的命令用来启动服务。

这种方法有两个缺点:
1. 启动时间长。init进程是串行启动,只有前一个进程启动完,才会启动下一个进程。
2. 启动脚本复杂。init进程只是执行启动脚本,不管其他事情。脚本需要自己处理各种情况,
这往往使得脚本变得很长。

Systemd 

就是为了解决这些问题而诞生的。它的设计目标是,为系统的启动和管理提供一套完整的解决方案。

根据 Linux 惯例,字母d是守护进程(daemon)的缩写。Systemd 这个名字的含义,就是它要守护整个系统。

进程组、会话、控制终端

• 进程组

shell里的每个进程都属于一个进程组,创建进程组的目的是用于简化向组内所有进程发送信号的操作,即如果一个信号是发给一个进程组,则这个组内的所有进程都会受到该信号【方便管理】。

• PGID进程组ID

进程组内的所有进程都有相同的PGID,等于该组组长的PID。(进程组组长:进程组中有一个进程担当组长。进程组ID(PGID)等于进程组组长的进程ID。已知一个进程,要得到该进程所属的进程组ID可以调用getpgrp。一个进程可以通过另一个系统调用setpgrp来加入一个已经存在的进程组或者创建一个新的进程组。

如果内核支持_POSIX_JOB_CONTROL(该宏被定义)则内核会为Shell 上的每一条命令行(可能由多个命令通过管道等连接)创建一个进程组。从这点上看,进程组不是进程的概念,而是shell上才有,所以在task_struct里并没有存储进程组id之类的变量。

进程组的生命周期到组中最后一个进程终止或其加入其他进程组(离开本进程组)为止。

会话

一般一个用户登录后新建一个会话,每个会话也有一个ID来标识(SID)。登录后的第一个进程叫做会话领头进程(session leader),通常是一个shell/bash。对于会话领头进程,其PID=SID。

控制终端

一个会话一般会拥有一个控制终端用于执行IO操作。会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端。与控制终端建立连接的会话领头进程也称为控制进程 (controlling process) 。一个会话只能有一个控制终端。

前台进程组

该进程组中的进程能够向终端设备进行读、写操作的进程组。例如登陆shell(例如bash)通过调用int tcsetpgrp(int fd, pid_t pgrp); 函数设置为某个进程组pgrp关联终端设备fd,该函数执行成功后,该进程组pgrp成为前台进程组。

后台进程组

该进程组中的进程只能够向终端设备写。

终端进程组ID

每个进程还有一个属性,终端进程组ID(TPGID),用来标识一个进程是否处于一个和终端相关的进程组中。前台进程组中的进程的TPGID=PGID,后台进程组的PGID≠TPGID。若该进程和任何终端无关,其值为-1。通过比较他们来判断一个进程是属于前台进程组,还是后台进程组。

进程组、对话期和控制终端关系

进程组、对话期和控制终端关系
  1. 每个会话有且只有一个前台进程组,但会有0个或者多个后台进程组。
  2. 产生在控制终端上的输入(Input)和信号(Signal)将发送给会话的前台进程组中的所有进程。对于输出(Output)来说,则是在前台和后台共享的,即前台和后台的打印输出都会显示在屏幕上。
  3. 终端上的连接断开时 (比如网络断开或 Modem 断开), 挂起信号将发送到控制进程(controlling process) 。
  4. 一个用户登录后创建一个会话。一个会话中只存在一个前台进程组,但可以存在多个后台进程组。第一次登陆后第一个创建的进程是shell,也就是会话的领头进程,该领头进程缺省处于一个前台进程组中并打开一个控制终端可以进行数据的读写。当在shell里运行一行命令后(不带&)创建一个新的进程组,命令行中如果有多个命令会创建多个进程,这些进程都处于该新建进程组中,shell将该新建的进程组设置为前台进程组并将自己暂时设置为后台进程组。

举例

  1. 打开第一个终端执行命令:
ping 127.0.0.1 -aq | grep icmp &  // 通过管道将两个命令串接起来ping –q不显示timeout信息,将其设置到后台并running
  1. 在第一个终端继续执行命令,在前台再新建一个进程组。【注意没有&】
ping 127.0.0.1 -aq | grep icmp //在前台再新建一个进程组,
  1. 开启第二个终端并运行
 ps axj | grep pts/0      即过滤只看pts/0里的会话

 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2109  2111  2111  2111 pts/0     2538 Ss    1000   0:01 bash
 2111  2503  2503  2111 pts/0     2538 S     1000   0:00 ping 127.0.0.1 -aq
 2111  2504  2503  2111 pts/0     2538 S     1000   0:00 grep --color=auto icmp
 2111  2538  2538  2111 pts/0     2538 S+    1000   0:00 ping 127.0.0.2 -aq
 2111  2539  2538  2111 pts/0     2538 S+    1000   0:00 grep --color=auto timeo

• SID都是2111,说明大家都在一个Session里 

• 有三个进程组PGID 2111,2503和2538。我们可以看到用|连起来的ping和grep是在一个进程组里的。

• 2538这个进程组是一个前台的进程组,因为其PGID==TGPID, 2503这个进程组是一个后台进程组

  1. 在第一个终端中执行Ctrl+C
  2. 在第二个终端里继续ps axj | grep pts/0
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
 2109  2111  2111  2111 pts/0     2111 Ss+   1000   0:01 bash
 2111  2503  2503  2111 pts/0     2111 S     1000   0:00 ping 127.0.0.1 -aq
 2111  2504  2503  2111 pts/0     2111 S     1000   0:00 grep --color=auto icmp

• 2538那个前台进程组的所有进程都消失了,说明信号会发给前台进程组的所有进程

 • 2111,即bash所在的那个进程组成为了前台进程组。

守护进程创建流程

守护进程创建流程如下:

1. 创建子进程,父进程退出 
2. 在子进程中创建新会话 
3. 改变当前目录为根目录 
4. 重设文件权限掩码 
5. 关闭文件描述符 

1.创建子进程,父进程退出

由于守护进程是脱离控制终端的,因此,完成第一步后就会在shell终端里造成一程序已经运行完毕的假象。之后的所有后续工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而在形式上做到了与控制终端的脱离。

由于父进程已经先于子进程退出,会造成子进程没有父进程,从而变成一个孤儿进程。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程收养。原先的子进程就会变成init进程的子进程。

2. 在子进程中创建新会话

setsid()函数的作用。一个进程调用setsid()函数后,会发生如下事件:

• 首先内核会创建一个新的会话,并让该进程成为该会话的leader进程,
• 同时伴随该session的建立,一个新的进程组也会被创建,同时该进程成为该进程组的组长。
• 该进程此时还没有和任何控制终端关联。若需要则要另外调用tcsetpgrp,前面讲前台进程组时介绍过。

调用setsid()有以下3个作用:

• 让进程摆脱原会话的控制。
• 让进程摆脱原进程组的控制。
• 让进程摆脱原控制终端的控制。

那么,在创建守护进程时为什么要调用setsid()函数呢?

读者可以回忆一下创建守护进程的第一步,在那里调用了fork()函数来创建子进程再令父进程退出。由于在调用fork()函数时,子进程全盘复制了父进程的会话期、进程组和控制终端等,虽然父进程退出了,但原先的会话期、进程组和控制终端等并没有改变,因此,还不是真正意义上的独立。而setsid()函数能够使进程完全独立出来,从而脱离所有其他进程和终端的控制。

详细见man 2 setsid。

3.改变当前目录为根目

这一步也是必要的步骤。使用fork()创建的子进程继承了父进程的当前工作目录。

由于在进程运行过程中,当前目录所在的文件系统(如“/mnt/usb”等)是不能卸载的,这对以后的使用会造成诸多的麻烦(如系统由于某种原因要进入单用户模式)。

因此,通常的做法是让“/”作为守护进程的当前工作目录,这样就可以避免上述问题。当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数是chdir()。

4. 重设文件权限掩码

文件权限掩码是指屏蔽掉文件权限中的对应位。

例如,有一个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。由于使用fork()函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。

因此,把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。设置文件权限掩码的函数是umask()。在这里,通常的使用方法为umask(0)。即赋予最大的能力。

5. 关闭文件描述符

同文件权限掩码一样,用fork()函数新建的子进程会从父进程那里继承一些已经打开的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法被卸载。

在上面的第(2)步之后,守护进程已经与所属的控制终端失去了联系,因此,从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf())输出的字符也不可能在终端上显示出来。

所以,文件描述符为0、1和2的3个文件(常说的输入、输出和报错这3个文件)已经失去了存在的价值,也应被关闭。

代码实现

/*
 关注一口Linux
*/

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h>
#include <stdio.h>
#include <sys/stat.h> 
#include <fcntl.h>
#include <string.h>

int main()
{
 pid_t pid;
 int i, fd;
 char *buf = "This is a Daemon\n";

 pid = fork();
 if (pid < 0) {
  printf("Error fork\n");
  exit(1);
 } 
 
 /* 第一步,父进程退出 */
 if (pid > 0) {
  exit(0); 
 }
 /* 第二步 */
 setsid();
 /* 第三步 */  
 chdir("/");  
 /* 第四步 */
 umask(0);
 /* 第五步 */  
 for(i = 0; i < getdtablesize(); i++) 
 {
  close(i);
 }
 
 /* 这时创建完守护进程,以下开始正式进入守护进程实际工作
  * 注意:由于此时守护进程完全脱离了控制终端,因此,不能像其他普通进程
  * 一样通过printf或者perror将错误信息输出到控制终端,一种通用的办
  * 法是使用syslog服务,将程序中的出错信息输入到系统日志文件中。
  * 本程序着重演示创建守护进程的步骤,暂不演示syslog。
  */

 while(1) {
  if ((fd = open("/tmp/daemon.log"
    O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0) {
   exit(1);
  }
  write(fd, buf, strlen(buf) + 1);
  close(fd);
  sleep(10);
 }
 
 exit(0);
}

执行结果由上图可见:• 守护进程./run 的UID为0;• 没有控制终端(TTY为?);• 终端进程组ID为-1;• 守护进程的父进程为1516,即systemd。



 



推荐阅读


【1】 100ASK_IMX6ULL arm板子如何显示图片、汉字、划线、背景色
【2】 到底什么是Cortex、ARMv8、arm架构、ARM指令集、soc?一文帮你梳理基础概念【科普】 必读
【3】 Linux信号量(2)-POSIX 信号量
【4】 手把手教Linux驱动8-Linux IO模型
【5】 C语言中的短路现象
【6】 C语言操作时间函数,实现定时执行某个任务小程序


本公众号全部原创干货已整理成一个目录,点击干货即可获得


后台回复进群」,即可加入技术交流群,进群福利:免费赠送Linux学习资料

一口Linux 写点代码,写点人生!
评论
  • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
    知白 2025-01-07 15:02 150浏览
  •  在全球能源结构加速向清洁、可再生方向转型的今天,风力发电作为一种绿色能源,已成为各国新能源发展的重要组成部分。然而,风力发电系统在复杂的环境中长时间运行,对系统的安全性、稳定性和抗干扰能力提出了极高要求。光耦(光电耦合器)作为一种电气隔离与信号传输器件,凭借其优秀的隔离保护性能和信号传输能力,已成为风力发电系统中不可或缺的关键组件。 风力发电系统对隔离与控制的需求风力发电系统中,包括发电机、变流器、变压器和控制系统等多个部分,通常工作在高压、大功率的环境中。光耦在这里扮演了
    晶台光耦 2025-01-08 16:03 80浏览
  • By Toradex 秦海1). 简介嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台。  2. 准备a). Verdin i.MX8MP ARM核心版配合Dahlia载板并
    hai.qin_651820742 2025-01-07 14:52 115浏览
  • 在智能网联汽车中,各种通信技术如2G/3G/4G/5G、GNSS(全球导航卫星系统)、V2X(车联网通信)等在行业内被广泛使用。这些技术让汽车能够实现紧急呼叫、在线娱乐、导航等多种功能。EMC测试就是为了确保在复杂电磁环境下,汽车的通信系统仍然可以正常工作,保护驾乘者的安全。参考《QCT-基于LTE-V2X直连通信的车载信息交互系统技术要求及试验方法-1》标准10.5电磁兼容试验方法,下面将会从整车功能层面为大家解读V2X整车电磁兼容试验的过程。测试过程揭秘1. 设备准备为了进行电磁兼容试验,技
    北汇信息 2025-01-09 11:24 14浏览
  • 一个真正的质量工程师(QE)必须将一件产品设计的“意图”与系统的可制造性、可服务性以及资源在现实中实现设计和产品的能力结合起来。所以,可以说,这确实是一种工程学科。我们常开玩笑说,质量工程师是工程领域里的「侦探」、「警察」或「律师」,守护神是"墨菲”,信奉的哲学就是「墨菲定律」。(注:墨菲定律是一种启发性原则,常被表述为:任何可能出错的事情最终都会出错。)做质量工程师的,有时会不受欢迎,也会被忽视,甚至可能遭遇主动或被动的阻碍,而一旦出了问题,责任往往就落在质量工程师的头上。虽然质量工程师并不负
    优思学院 2025-01-09 11:48 25浏览
  • 本文介绍编译Android13 ROOT权限固件的方法,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。关闭selinux修改此文件("+"号为修改内容)device/rockchip/common/BoardConfig.mkBOARD_BOOT_HEADER_VERSION ?= 2BOARD_MKBOOTIMG_ARGS :=BOARD_PREBUILT_DTB
    Industio_触觉智能 2025-01-08 00:06 100浏览
  • 故障现象一辆2017款东风风神AX7车,搭载DFMA14T发动机,累计行驶里程约为13.7万km。该车冷起动后怠速运转正常,热机后怠速运转不稳,组合仪表上的发动机转速表指针上下轻微抖动。 故障诊断 用故障检测仪检测,发动机控制单元中无故障代码存储;读取发动机数据流,发现进气歧管绝对压力波动明显,有时能达到69 kPa,明显偏高,推断可能的原因有:进气系统漏气;进气歧管绝对压力传感器信号失真;发动机机械故障。首先从节气门处打烟雾,没有发现进气管周围有漏气的地方;接着拔下进气管上的两个真空
    虹科Pico汽车示波器 2025-01-08 16:51 92浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球无人机锂电池产值达到2457百万美元,2024-2030年期间年复合增长率CAGR为9.6%。 无人机锂电池是无人机动力系统中存储并释放能量的部分。无人机使用的动力电池,大多数是锂聚合物电池,相较其他电池,锂聚合物电池具有较高的能量密度,较长寿命,同时也具有良好的放电特性和安全性。 全球无人机锂电池核心厂商有宁德新能源科技、欣旺达、鹏辉能源、深圳格瑞普和EaglePicher等,前五大厂商占有全球
    GIRtina 2025-01-07 11:02 128浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2025-01-09 09:58 19浏览
  • 大模型的赋能是指利用大型机器学习模型(如深度学习模型)来增强或改进各种应用和服务。这种技术在许多领域都显示出了巨大的潜力,包括但不限于以下几个方面: 1. 企业服务:大模型可以用于构建智能客服系统、知识库问答系统等,提升企业的服务质量和运营效率。 2. 教育服务:在教育领域,大模型被应用于个性化学习、智能辅导、作业批改等,帮助教师减轻工作负担,提高教学质量。 3. 工业智能化:大模型有助于解决工业领域的复杂性和不确定性问题,尽管在认知能力方面尚未完全具备专家级的复杂决策能力。 4. 消费
    丙丁先生 2025-01-07 09:25 123浏览
  • 在智能家居领域中,Wi-Fi、蓝牙、Zigbee、Thread与Z-Wave等无线通信协议是构建短距物联局域网的关键手段,它们常在实际应用中交叉运用,以满足智能家居生态系统多样化的功能需求。然而,这些协议之间并未遵循统一的互通标准,缺乏直接的互操作性,在进行组网时需要引入额外的网关作为“翻译桥梁”,极大地增加了系统的复杂性。 同时,Apple HomeKit、SamSung SmartThings、Amazon Alexa、Google Home等主流智能家居平台为了提升市占率与消费者
    华普微HOPERF 2025-01-06 17:23 211浏览
  • 在过去十年中,自动驾驶和高级驾驶辅助系统(AD/ADAS)软件与硬件的快速发展对多传感器数据采集的设计需求提出了更高的要求。然而,目前仍缺乏能够高质量集成多传感器数据采集的解决方案。康谋ADTF正是应运而生,它提供了一个广受认可和广泛引用的软件框架,包含模块化的标准化应用程序和工具,旨在为ADAS功能的开发提供一站式体验。一、ADTF的关键之处!无论是奥迪、大众、宝马还是梅赛德斯-奔驰:他们都依赖我们不断发展的ADTF来开发智能驾驶辅助解决方案,直至实现自动驾驶的目标。从新功能的最初构思到批量生
    康谋 2025-01-09 10:04 21浏览
  • 「他明明跟我同梯进来,为什么就是升得比我快?」许多人都有这样的疑问:明明就战绩也不比隔壁同事差,升迁之路却比别人苦。其实,之间的差异就在于「领导力」。並非必须当管理者才需要「领导力」,而是散发领导力特质的人,才更容易被晓明。许多领导力和特质,都可以通过努力和学习获得,因此就算不是天生的领导者,也能成为一个具备领导魅力的人,进而被老板看见,向你伸出升迁的橘子枝。领导力是什么?领导力是一种能力或特质,甚至可以说是一种「影响力」。好的领导者通常具备影响和鼓励他人的能力,并导引他们朝着共同的目标和愿景前
    优思学院 2025-01-08 14:54 82浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球中空长航时无人机产值达到9009百万美元,2024-2030年期间年复合增长率CAGR为8.0%。 环洋市场咨询机构出版了的【全球中空长航时无人机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球中空长航时无人机总体规模,包括产量、产值、消费量、主要生产地区、主要生产商及市场份额,同时分析中空长航时无人机市场主要驱动因素、阻碍因素、市场机遇、挑战、新产品发布等。报告从中空长航时
    GIRtina 2025-01-09 10:35 16浏览
  • 1月7日-10日,2025年国际消费电子产品展览会(CES 2025)盛大举行,广和通发布Fibocom AI Stack,赋智千行百业端侧应用。Fibocom AI Stack提供集高性能模组、AI工具链、高性能推理引擎、海量模型、支持与服务一体化的端侧AI解决方案,帮助智能设备快速实现AI能力商用。为适应不同端侧场景的应用,AI Stack具备海量端侧AI模型及行业端侧模型,基于不同等级算力的芯片平台或模组,Fibocom AI Stack可将TensorFlow、PyTorch、ONNX、
    物吾悟小通 2025-01-08 18:17 20浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦