进程间关系与守护进程

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

进程间关系与守护进程

收录于专栏[Linux学习]
本专栏旨在分享学习Linux的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 进程组

什么是进程组

组长进程

2. 会话

什么是会话

如何创建会话 

会话 ID(SID) 

3. 控制终端

4. 作业控制

什么是作业和作业控制?

作业号 

作业状态 

​作业的挂起与切回 

作业挂起 

作业切回 

查看后台执行或挂起的作业 

作业控制相关的信号 

5. 守护进程


1. 进程组

什么是进程组

之前我们提到了进程的概念,其实每一个进程除了有一个进程 ID(PID)之外,还属于一个进程组。进程组是一个或者多个进程的集合,一个进程组可以包含多个进程。每一个进程组也是有唯一的进程组 ID(PGID),并且这个 PGID 类似于进程 ID,同样是一个正整数,可以存放在 pid_t 数据类型中。 

-e:选项表示 every 的意思,表示输出每一个进程信息

-o:选项以逗号操作符(,)作为定界符,可以指定要输出的列

组长进程

每一个进程组都有一个组长进程。组长进程的 ID 等于其进程 ID。我们可以通过 ps 命令看到组长进程的现象:

从结果上看 ps 进程的 PID 和 PGID 相同,那就是说明 ps 进程是该进程组的组长进程,该进程包括 ps 和 cat 两个进程。

进程组组长的作用:进程组长可以创建一个进程组或者创建该组中的进程

进程组的声明周期:从进程组创建开始到其中最有一个进程离开为止。

注意:某个进程中有一个进程存在,则该进程组就存在,这与其组长进程是否已经终止无关。

2. 会话

什么是会话

刚刚我们谈到了进程组的概念,那么会话又是什么呢?会话其实和进程组息息相关,会话可以看成是一个或多个进程组的集合,一个会话可以包含多个进程。每一个会话也有一个会话 ID(SID)

通常我们都是使用 管道 将几个进程编程一个进程组。如上如所示进程组2和进程组3可能是由下列命令形成的:

proc2 | proc3 &
proc4 | proc5 | proc6 &

我们举一个例子观察一下这个现象:

a 选项表示不仅当前用户的进程,也列出所有其他用户的进程

x 选项表示不仅列出有控制终端的进程,也列出所有无控制终端的进程

j 选项表示列出与作业控制相关的信息,作业控制后续再说

grep 的 -v 选项表示反向过滤,即不过滤带有 grep 字段相关的进程

从上述结果来看 3 个进程对应的 PGID 相同,即属于同一个进程组。  

如何创建会话 

可以调用 setseid 函数创建一个会话,前提是调用进程不能是一个进程的组长。

#include <unistd.h>
功能:创建会话
返回值:创建成功返回 SID,失败返回-1
pid_t setsid(void);

该接口调用之后会发生:

1. 调用进程会变成新会话的会话首进程。此时,新会话只有唯一的一个进程

2. 调用进程会变成进程组组长。新进程组 ID 就是当前调用进程 ID

3. 该进程没有控制终端。如果在调用 setsid 之前该进程存在控制终端,则调用之后会切断联系

需要注意的是:这个接口如果调用进程是进程组组长,则会报错,为了避免这种情况,我们通常的使用方法是先调用 fork 创建子进程,父进程终止,子进程继续执行,因为子进程会继承父进程的进程组 ID,而进程 ID 则是新分配的,就不会出现错误的情况。 

会话 ID(SID) 

上边我们提到了会话 ID,那么会话 ID 是什么呢?我们可以先说一下会话首进程,会话首进程是具有唯一进程 ID 的单个进程,那么我们可以将会话首进程的 ID 当做是会话 ID。注意:会话 ID 在有些地方也被称为 会话首进程的进程组 ID,因为会话首进程总是一个进程组的组长进程,所以两者是等价的。 

3. 控制终端

先说一下什么是控制终端?

在 UNIX 系统中,用户通过终端登录系统后得到一个 Shell 进程,这个终端称为 Shell 进程的控制终端。控制终端是保存在 PCB 中的信息,我们知道 fork 进程会复制 PCB 中的信息,因此 Shell 进程启动的其他进程的控制终端也是这个终端。 默认情况下没有重定向,每个进程的标准输入、标准输出和标准错误都指向控制终端,进程从标准输入读也就是读用户的键盘输入,进程往标准输出或标准错误输出写也就是输出到显示器上。另外会话、进程组以及控制终端还有一些其他的关系,我们在下边详细介绍:

一个会话可以有一个控制终端,通常会话首进程打开一个终端(终端设备或伪终端设备)后,该终端就成为该会话的控制终端。

建立与控制终端连接的会话首进程被称为控制进程。

一个会话中的几个进程组可以分成一个前台进程组以及一个或者多个后台进程组

如果一个会话有一个控制终端,则它有一个前台进程组,会话中的其他进程组则为后台进程组的所有进程。

如果终端接口检测到调制解调器(或网络)已经断开,则将挂断的信号发送给这些特性的关系如下图所示:

 

4. 作业控制

什么是作业和作业控制?

作业是针对用户来讲,用户完成某项任务而启动的进程,一个作业既可以只包含一个进程,也可以包含多个进程,进程之间互相协作完成任务,通常是一个进程管道。

Shell 分前后台控制的不是进程而是作业 或者进程组。一个前台作业可以由多个进程组成。一个后台作业也可以由多个进程组成,Shell 可以同时运行一个前台作业和任意多个后台作业,这称为作业控制 

例如下列命令就是一个作业,它包括两个命令,在执行时 Shell 将在前台启动由两个进程组成的作业:

cat /etc/filesystems | head -n 5

作业号 

放在后台执行的程序或命令称为后台命令,可以在命令的后面加上 & 符号从而让 Shell 识别这是一个后台命令,后台命令不用等待该命令执行完成,就可立即接收新的命令,另外后台进程执行完后会返回一个作业号以及一个进程号(PID)。 

例如 下面的命令在后台启动了一个作业,该作业由两个进程组成,两个进程都在后台运行:

cat /etc/filesystems | grep ext &

执行结果如下:

[1] 2202ext4ext3ext2# 按下回车[1]+ 完成 cat /etc/filesystems | grep --color=auto ext

第一行表示作业和进程 ID,可以看到作业号是 1,进程 ID 是2022

第 3-4 行表示该程序运行的结果,过滤 /etc/filesystems 有关 ext 的内容

第 6 行分别表示作业号、默认作业、作业状态以及所执行的命令

关于默认作业:对于一个用户来说,只能有一个默认作业(+),同时也只能有一个即将成为默认作业的作业(-),当默认作业退出后,该作业会成为默认作业。

+:表示该作业号是默认作业

-:表示该作业即将成为默认作业

无符号:表示其他作业

作业状态 

常见的作业状态如下表所示:

作业的挂起与切回 

作业挂起 

我们在执行某个作业时,可以通过 ctrl + z 键将该作业挂起,然后 Shell 会显示相关的作业号、状态以及所执行的命令信息。

例如我们运行一个死循环的程序、通过 ctrl + Z 将该作业挂起,观察一个对应的作业状态:

#include <stdio.h>int main()
{while(1){printf("hello\n");}return 0;
}

可以发现通过 ctrl + z 将作业挂起,该作业状态已经变为了停止状态 

作业切回 

如果想将挂起的作业切回,可以通过 fg 命令,fg 后面可以跟作业号或作业的命令名称。如果参数缺省则会默认将作业号为 1 的作业切到前台来执行,若当前系统只有一个作业在后台进行,则可以直接使用 fg 命令不带参数直接切回。具体的参数参考如下:

参数含义
%nn为正整数,表示作业号
%string以字符串开头的命令所对应的作业
%?string包含字符串的命令所对应的作业
%+或%%最近提交的一个作业
%-倒数第二个提交的作业

例如我们把刚刚挂起来的 ./test 作业切回到前台:

运行结果为开始无限循环打印 hello,可以发现该作业已经切换到前台了。

注意:当通过 fg 命令切回作业时,若没有指定作业参数,此时会将默认作业切到前台执行,即带有 “*” 的作业号的作业 

查看后台执行或挂起的作业 

我们可以直接通过输入 jobs 命令查看本用户当前后台执行或挂起的作业

参数 -1 则显示作业的详细信息

参数 -p 则只显示作业的 PID 

例如,我们先在后台及前台运行两个作业,并将前台作业挂起,来用 jobs 命令查看作业相关的信息:

作业控制相关的信号 

上面我们提到了键入 ctrl + z 可以将前台作业挂起,实际上是将 STGTSTP 信号发送至前台进程组作业中的所有进程,后台进程组中的作业不受影响。在 unix 系统中,存在 3 个特殊字符可以使得终端驱动程序产生信号,并将信号发送至前台进程组作业,它们分别是 :

crtl + C :中断字符,会产生 SIGINT 信号

ctrl + \ :退出字符,会产生 SIGQUIT 信号

ctrl + z :挂起字符,会产生 STGSTP 信号 

终端的 I/O (即标准输入和标准输出)和终端产生的信号总是从前台进程组作业连接打破实际终端。

5. 守护进程

#include <iostream>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>const char* root = "/";
const char* dev_null = "/dev/null";void Daemon(bool ischdir,bool isclose)
{//1. 忽略可能引起程序员异常退出的信号signal(SIGCHLD,SIG_IGN);signal(SIGPIPE,SIG_IGN);//2. 让自己不要成为组长if(fork > 0)exit(0);//3. 设置让自己成为一个新的会话,后面的代码其实是子进程在走setsid();//4. 每一个进程都有自己的 CWD,是否将当前进程的 CWD 更改成为 /根目录if(ischdir)chdir(root);//5. 已经变成守护进程啦,不需要和用户的输入输出,错误进行关联if(isclose){close(0);close(1);close(2);}else {// 这里一般建议就用这种int fd = open(dev_null,O_RDWR);if(fd > 0){dup2(fd,0);dup2(fd,1);dup2(fd,2);close(fd);}}
}

这个 Daemon 函数的目的是将一个程序转化为守护进程。它完成了一下几个步骤:

1. 忽略一些信号,防止进程异常退出

2. 使用 fork 确保父进程退出,使子进程成为孤儿进程。

3. 使用 setsid 创建新的会话,并使进程不再与终端相关。

4. 可选地将当前工作目录更改为根目录 / ,避免占用启动目录。

5. 关闭或重定向标准输入输出,确保守护进程不再与终端交互

通过这些步骤,程序就能以守护进程的方式在后台运行,不再依赖用户终端或任何终端的交互。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/64951.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP 16、实践 ③ 找出特定字符在字符串中的位置】

看着父亲苍老的白发和渐渐老态的面容 希望时间再慢一些 —— 24.12.19 一、定义模型 1.初始化模型 ① 初始化父类 super(TorchModel, self).__init__()&#xff1a; 调用父类 nn.Module 的初始化方法&#xff0c;确保模型能够正确初始化。 ② 创建嵌入层 self.embedding n…

javaEE-多线程编程-3

目录 java 常见的包 : 回调函数: 什么是线程: 第一个线程: 验证多线程执行: 内核: 调用sleep()方法: 执行结果分析: 线程创建的几种方式: 1.继承Thread类,重写run()方法. 2.实现Runnable接口,重写run()方法. 3.继承Thread类,重写run()方法.但使用匿名内部类 4.实现…

怎么在idea中创建springboot项目

最近想系统学习下springboot&#xff0c;尝试一下全栈路线 从零开始&#xff0c;下面将叙述下如何创建项目 环境 首先确保自己环境没问题 jdkMavenidea 创建springboot项目 1.打开idea&#xff0c;选择file->New->Project 2.选择Spring Initializr->设置JDK->…

设计模式期末复习

一、设计模式的概念以及分类 是一套被反复使用&#xff0c;多数人知晓&#xff0c;经过分类编目&#xff0c;代码设计经验的总结&#xff0c;描述了在软件设计的过程中不断重复发生的问题&#xff0c;以及该问题的解决方案&#xff0c;他是解决特定问题的一系列套路&#xff0c…

Github——网页版上传文件夹

第一步&#xff1a;创建一个新的仓库或进入已存在的仓库页面 第二步&#xff1a;点进对应的文件夹下&#xff0c;然后 点击 “Upload files” 第三步&#xff1a;将文件夹拖拽到上传区域 打开资源管理器&#xff0c;将要上传的文件夹从计算机中拖拽到上传区域。 注意&#xf…

高级的SQL查询技巧有哪些?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于高级SQL查询技巧方面的相关内容&#xf…

FastStone 10.x 注册码

简介 FastStone Capture是一款经典好用的屏幕截图软件&#xff0c;在屏幕截图领域具有广泛的应用和众多优势。 软件基本信息 FastStone Capture体积小巧&#xff0c;占用内存少&#xff0c;这使得它在运行时不会给计算机系统带来过多的负担&#xff0c;即使在配置较低的电脑…

K8S详解(5万字详细教程)

目录 ​编辑 一、集群管理命令 二、命名空间 1. 获取命名空间列表 2. 创建命名空间 3. 删除命名空间 4. 查看命名空间详情 三、Pod 1. Pod概述 2. Pod相位状态 3. 管理命令 3.1 获取命名空间下容器(pod)列表 3.2 查看pod的详细信息 3.3 创建 && 运行 3.4 …

费舍尔信息矩阵全面讲述

费舍尔信息矩阵&#xff08;Fisher Information Matrix&#xff09; 费舍尔信息矩阵是统计学中一个非常重要的概念&#xff0c;尤其在参数估计、最大似然估计&#xff08;MLE&#xff09;和贝叶斯推断中具有广泛的应用。它反映了参数估计的不确定性程度&#xff0c;也可以用来…

Zookeeper的监听机制

Zookeeper的监听机制是其实现分布式协调服务的一个核心功能。 它允许客户端注册Watcher&#xff08;观察者&#xff09;来监听特定的Znode&#xff08;节点&#xff09;上的事件&#xff0c;当Znode的状态发生变化时&#xff0c;Zookeeper会向注册了Watcher的客户端发送通知。…

[原创](Modern C++)现代C++的第三方库的导入方式: 例如Visual Studio 2022导入GSL 4.1.0

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共23年] 职业生涯: 21年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi、XCode、Eclipse…

2002 - Can‘t connect to server on ‘192.168.1.XX‘ (36)

参考:2002 - Can‘t connect to server on ‘192.168.1.XX‘ (36) ubantu20.04&#xff0c;mysql5.7.13 navicat 远程连接数据库报错 2002 - Can’t connect to server on ‘192.168.1.61’ (36) 一、查看数据库服务是否有启动&#xff0c;发现有启动 systemctl status mysql…

漏洞检测工具:允许TRACE方法漏洞

允许TRACE方法漏洞 漏洞定义 TRACE方法是HTTP协议中定义的一种调试方法&#xff0c;主要用于测试或诊断Web服务器连接。Web服务器在配置时未正确禁用HTTP TRACE方法&#xff0c;从而允许客户端向服务器发送TRACE请求&#xff0c;并导致服务器返回可能包含敏感信息的响应。 漏…

linux socket编程之udp_dict_serve服务端--引入配置文件

注意&#xff1a;本篇博客只是对上一篇博客功能的增加 1.创建配置文件(翻译) Dict.txt apple: 苹果 banana: 香蕉 cat: 猫 dog: 狗 book: 书 pen: 笔 happy: 快乐的 sad: 悲伤的 run: 跑 jump: 跳 teacher: 老师 student: 学生 car: 汽车 bus: 公交车 love: 爱 hate: 恨 hell…

ESP32S3 使用LVGL驱动LCD屏(ST7789主控)

ESP32S3 使用LVGL驱动LCD屏&#xff08;ST7789主控&#xff09; 目录 1 分析原理图 2 驱动、点亮LCD(ST7789) 2.1 在工程中添加目录、文件 2.2 添加esp_lvgl_port组件 2.3 对工程进行必要的配置 2.4 编写必要代码 3 烧录、验证 1 分析原理图 要使用SOC驱动LCD屏&#…

Sigrity Optimize PI CapGen仿真教程文件路径

为了方便读者能够快速上手和学会Sigrity Optimize PI和 Deacap Generate 的功能&#xff0c;将Sigrity Optimize PI CapGen仿真教程专栏所有文章对应的实例文件上传至以下路径 https://download.csdn.net/download/weixin_54787054/90171471?spm1001.2014.3001.5503

2024年“羊城杯”粤港澳大湾区网络安全大赛 初赛 Web数据安全AI 题解WriteUp

文章首发于【先知社区】&#xff1a;https://xz.aliyun.com/t/15442 Lyrics For You 题目描述&#xff1a;I have wrote some lyrics for you… 开题。 看一下前端源码&#xff0c;猜测有路径穿越漏洞 http://139.155.126.78:35502/lyrics?lyrics../../../../../etc/passw…

NLP 中文拼写检测开源-03-hunspell 拼写纠正算法入门介绍 CSC

拼写纠正系列 NLP 中文拼写检测实现思路 NLP 中文拼写检测纠正算法整理 NLP 英文拼写算法&#xff0c;如果提升 100W 倍的性能&#xff1f; NLP 中文拼写检测纠正 Paper java 实现中英文拼写检查和错误纠正&#xff1f;可我只会写 CRUD 啊&#xff01; 一个提升英文单词拼…

SpringCloud 运用(3)—— Nacos配置中心

上一篇&#xff1a;SpringCloud 入门&#xff08;2&#xff09;—— 跨服务调度-CSDN博客 Nacos是阿里巴巴开源的服务发现与配置管理基础设施&#xff0c;旨在帮助开发者更轻松地构建云原生应用。它提供了一组简单易用的特性集&#xff0c;支持动态服务发现、配置管理和服务管理…

门户系统需要压测吗?以及门户系统如何压力测试?

一、门户系统为什么要进行压力测试&#xff1f; 首先一点要明确一下&#xff0c;统一门户上线以后&#xff0c;将是所有应用系统的入口&#xff0c;对应门户稳定性要求较高&#xff0c;门户实现了统一入口和统一认证&#xff0c;系统宕机将影响其他系统使用。一般部署架构要求…