进程间关系和守护进程

序言

 当我们使用指令 ps 查看进程的相关信息时,在以前我们只是关注该进程的 PID(该进程的标识符)PPID(其父进程的标识符) 以及 STAT(该进程的状态)
 那 PGIDSID 又是什么?有什么作用呢?


1. 进程组

1.1 什么是进程组?

 当我们启动程序执行相应的任务时,我们的任务可能只是创建了一个进程:

 1 #include <iostream>2 #include <unistd.h>3 4 int main()5 {6     while(1)7     {8         std::cout << "I am running, my pid is " << getpid() << std::endl;9         sleep(1);10     }11     return 0;12 }

我们使用指令 ps 查看进程信息:
在这里插入图片描述

在这里的 PGID 就是代表进程组,进程组的 idPID 保持一致。当我们的进程组只包含一个进程时,进程的 ID 等于其进程 ID

 那如果我们的任务包含多个进程呢?举个栗子:
在这里插入图片描述
当一个进程组包含多个进程时,进程组的 ID 和第一个创建的进程的 ID 保持一致。

 总结一下,进程组是一个或者多个进程的集合, 一个进程组可以包含多个进程

1.2 组长进程

 每一个进程组都包含一个组长进程,组长进程的 ID 就是该进程组的 ID。根据上面代码的举例,我们不难得出以下结论:

  • 当一个进程组只有一个进程时,该进程就是组长进程
  • 当一个进程组包含多个进程时,首先创建的进程为组长进程

一个进程组的生每周期取决于最后终止的进程而非是组长进程。


2. 会话

2.1 什么是会话

 会话可以看成是 一个或多个进程组的集合, 一个会话可以包含多个进程组。每一个会话也有一个会话 ID(SID)
 创建一个新的会话时可以简单理解为 创建终端文件和启动 bash 进程

  • 终端:终端是用户与操作系统进行交互的界面。
  • bashbashLinux上 最常用的 Shell 之一,Shell 是运行在终端上的程序,它提供了用户与操作系统交互的接口。

怎么来证明呢?现在我在 XShell 上只是启动一个会话,查看我们的终端文件和 bash 进程:
在这里插入图片描述
在这里插入图片描述

可以看到只存在一个终端文件和 bash 进程,那我们再创建一个回话呢:
在这里插入图片描述在这里插入图片描述
现在就变成了两个终端文件和两个 bash 进程。

 所以在每一次登录时,都会为我们自动建立一次会话。会话的 id 和第一个创建的进程的 id 保持一致,在大多数情况下都是我们的 bash,除非是我们手动创建的会话。

2.2 创建一个会话

 可以调用 setsid 函数来创建一个会话, 前提是 调用进程不能是一个进程组的组长。
 大家都知道可以使用 ctrl + c 来终止当前程序(需要是前台的程序,后面会说)的执行吧,但是该程序必须是当前会话下的程序。那不是废话吗,我在我会话下启动的程序肯定就是啊,难不成跑到别处去了?
 没认识 setsid 之前你的话是对的,但是认识之后就不一定了,举个栗子:

   1 #include <iostream>2 #include <unistd.h>3 4 int main()5 {6     // child7     if(fork() ==  0)8     {// 创建新的会话9         setsid();10         while(1)11         {12             std::cout << "I am child process, my pid is " << getpid() << std::endl;13             sleep(2);14         }15     }16     // parent17     else18     {19         while(1)20         {21             std::cout << "I am parent process, my pid is " << getpid() << std::endl;22             sleep(2);23          }24     }25 26     return 0;27 }

现在我们运行这段程序:
在这里插入图片描述
程序正常运行,但是终止进程后子进程依然执行,这是因为子进程属于其他会话,不归当前会话管。那除了重启大法没办法终止他了吗?肯定不是,我们还有 kill 指令。


3. 前后台任务

3.1 前台任务

 前台任务会占据终端的输入输出,即它会接收你通过键盘输入的命令或数据,并将它的输出结果直接显示在终端上。前台任务会阻塞终端,直到它完成或者被你明确地放到后台执行。简而言之,前台任务会占有终端文件! 比如:

   1 #include <iostream>2 #include <unistd.h>3 4 int main()5 {6     while(true) sleep(1);7     return 0;8 } 

现在我们运行该程序,并向终端输入指令:
在这里插入图片描述
可以看到并没有任何结果,这是因为我们输入的指令都是被 bash 指令接受之后创建子进程执行的,但是现在终端文件被该进程占有了,自然 bash 收不到了。

3.2 后台任务

 后台任务是指那些在终端之外运行的任务,它们 不会直接占据终端的输入输出。后台任务可以在你执行其他任务或关闭终端时继续运行。要将一个任务放到后台执行,你可以在命令的末尾加上 & 符号。
 还是上一段程序,但是在运行时在最后加上 &:
在这里插入图片描述

可以看到,我们指令的执行并没有受到干扰。

 那我怎么查看我后台任务的执行情况呢,使用指令 jobs [-l]:
在这里插入图片描述

3.3 后台任务切回前台

 只需要使用指令 fg nn 代表该任务的编号:
在这里插入图片描述

3.4 前台任务切回后台

 首先我们需要使用指令 ctrl + z 将该任务暂停,之后使用指令 bg n 将该任务切换到后台:
在这里插入图片描述


4. 守护进程

 我们运行一个普通的进程时,不管是前台还是后台,当我们一退出,会话一结束。我们执行的进程也会随之终止,但是在很多应用场景下,服务是不能停的!不可能程序员一下班,我们的应用就罢工了吧!
 所以有了守护进程,守护进程通常用于 提供需要持续运行的服务,如网络服务(Web服务器、FTP服务器等)、数据库服务等。这些服务在系统运行期间 一直保持运行状态,确保用户可以随时访问。
 那我们如何创建一个守护进程呢,关键是 创建一个新的会话,当我们的会话结束时,该会话不受影响!但是只是靠一个进程是做不到的,因为 调用 setsid 的函数不能是进程组长!包含一个进程的进程组,该进程就是组长!解决方法也很简单,一个进程不行那就创建一个子进程嘛,创建的过程如下:

#pragma once#include <unistd.h>
#include <signal.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>void Daemon(const std::string &newpath = "")
{// 防止一些异常退出信号signal(SIGCHLD, SIG_IGN);// 创建子进程,父进程退出if (fork() > 0)exit(0);// 设置一个新的会话setsid();// 关闭原来的文件描述符int fd = open("/dev/null", O_RDWR);if (fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}// 是否更改工作路径if (!newpath.empty()){chdir(newpath.c_str());}
}

 父进程的作用就是创建一个子进程,之后父进程的生命周期就结束了。子进程创建了一个新的会话,脱离了原来的会话。
 在这里为什么需要关闭原来的文件描述符呢?这是因为现有的文件描述符还指向原来会话的文件,这是不严谨的,因为我们当前已经脱离了原来的会话。在这里没有直接的关闭,因为 考虑到后续场景可能使用到读写操作。所以我们让他指向一个空的文件(类似于空指针)。是否需要切换路径和使用场景相关。


5. 总结

 在这篇文章中,我们介绍了进程的组以及会话的概念,还实现了一下守护进程功能的函数。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

视频工具EasyDarwin将本地视频生成RTSP给WVP拉流列表

效果 ffmpeg生成rtsp流 EasyDarwin的rtsp端口默认的是10054, 使用ffmpeg将本地视频转到EasyDarwin的rtsp。 F:\rtsp\ffmpeg-7.0.2-essentials_build\bin>ffmpeg -re -i F:\rtsp\123.mp4 -rtsp_transport tcp -vcodec h264 -f rtsp rtsp://127.0.0.1:10054/video11 它的直播…

基于SpringBoot+Vue+MySQL的在线视频教育平台

系统展示 用户前台界面 管理员后台界面 系统背景 随着信息技术的飞速发展和互联网普及率的不断提高&#xff0c;传统教育模式正面临深刻变革。在线视频教育平台作为数字化教育的重要载体&#xff0c;以其灵活性强、资源丰富、覆盖广泛等优势&#xff0c;逐渐成为人们获取知识、…

RS232

What is RS232 Protocol? In RS232, ‘RS’ stands for Recommended Standard. It defines the serial communication using DTE and DCE signals. Here, DTE refers to Data Terminal Equipment and DCE refers to the Data Communication Equipment. Example of DTE device…

1184. 公交站间的距离(24.9.16)

题目 环形公交路线上有n个站&#xff0c;按次序从 0 到n - 1进行编号。已知每一对相邻公交站之间的距离&#xff0c;distance[i]表示编号为i的车站和编号为(i 1) % n的车站之间的距离。环线上的公交车都可以按顺时针和逆时针的方向行驶。要求返回乘客从出发点start到目的地de…

数组学习内容

动态初始化 只给长度&#xff0c;数据类型【】 数组名new 数据类型【数组长度】 内存图

打造最佳自闭症患全寄宿学校:为孩子的未来保驾护航

在广州这座繁华而温暖的城市中&#xff0c;隐藏着一片专为自闭症儿童精心打造的避风港——星贝育园自闭症儿童寄宿制学校。这里&#xff0c;不仅是一所学校&#xff0c;更是无数家庭希望的灯塔&#xff0c;用爱与专业为孩子们铺设了一条通往更加独立自主生活的道路。 一、爱的…

泛读笔记:从Word2Vec到BERT

自然语言处理(NLP)模型的发展历史 1.统计方法时期&#xff1a;使用贝叶斯方法、隐马尔可夫模型、概率模型等传统统计方法 2.机器学习时期&#xff1a;支持向量机(SVM)、决策树模型、随机森林、朴素贝叶斯等传统机器学习方法 3.深度学习革命&#xff1a;各种新的深度学习模型&am…

卸载完mathtype后,删除word加载项中的mathtype

请参考博客“卸载完mathtype后&#xff0c;word加载项中还是有mathtype的解决方法_怎么删除word加载项里的mathtype-CSDN博客”以及 “安装卸载MathType经验解决MathType DLL找不到的问题——超实用_mathtype dll cannot-CSDN博客” 如果在删除.dotm文件时&#xff0c;删不掉…

01 企业成长助力计划

1,企业和军队一个共同点: 必须不断打胜仗,才能持续活下去并活的有力量。 2,从知道到做到,其实非常艰难 3,大道至简,知易行难 4,华为值得大家学习么,哪些值得学习,学习什么,怎么学。 5,企业发展的瓶颈 6,学习什么? 学习华为是怎么学习别人的。 学习华为是如何批…

TCP协议分析《实验报告》

一、实验目的 1、理解TCP协议&#xff1b; 2、掌握TCP协议三次握手建立连接和四次挥手释放连接的过程&#xff1b; 3、理解TELNET协议及工作过程&#xff1b; 4、掌握TCP协议分析方法。 二、实验设备和环境 1、硬件设备&#xff1a;PC机或笔记本电脑&#xff1b; 2、软件…

金融行业中如何利用数据中台的数据来有效的驱动业务决策呢?

前言​ 在金融行业中&#xff0c;利用数据中台的数据来有效驱动业务决策是一个复杂而关键的过程。其实我们的核心就是帮助金融机构最大化数据中台的价值&#xff0c;并推动业务决策的科学性和准确性。本文我从技术的角度来剖析一下这一过程。​ 什么是数据中台&#xff1f;​…

【C++】学完c语言后的c++基础知识补充!(命名空间、输入和输出、缺省函数、函数重载、引用、内联函数代替宏、nullptr代替NULL)

一. 命名空间 1. 定义 出现的意义&#xff1a;解决各种函数、关键词和类的名称冲突问题。 定义方式&#xff1a;namespace 命名空间的名字 { } &#xff08;注意&#xff01;}后面不加&#xff1b;&#xff09; namespace 是关键词命名空间的…

前端基础知识(HTML+CSS+JavaScript)

文章目录 一、HTML1.1 HTML 基础&#xff1a;1.1.1 HTML 的概念&#xff1a;1.1.2 认识 HTML 标签&#xff1a;1.1.3 HTML 文件基本结构&#xff1a;1.1.4 标签层次结构&#xff1a; 1.2 HTML 快速入门&#xff1a;1.3 HTML常见标签&#xff1a;1.3.1 标题标签&#xff1a;h1-h…

智能家政保洁|基于java和vue的智能家政保洁预约系统(源码+数据库+文档)

智能家政保洁预约系统 目录 基于java和vue的智能家政保洁预约系统 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&#xf…

Android应用程序启动源码分析

文章目录 Android应用程序启动源码分析一、启动流程二、Launcher通知AndroidOS(用户点击图标)2.1 Activity.java2.2 Instrumentation.java2.3 ActivityTaskManagerService.java2.4 ActivityStarter.java2.5 RootWindowContainer.java2.5.1 Task.java2.5.2 TaskFragment.java 2.…

JS高级(二)、深入对象:构造函数;Object,Array,String,Number包装类;原型对象,原型链

文章目录 一、深入对象1. 构造函数2. 实例成员&静态成员(1)、实例成员(2)、静态成员 3. 包装类(1)、Object&#xff1a;keys&#xff0c;values(2)、Array&#xff1a;forEach&#xff0c;map&#xff0c;join&#xff0c;every&#xff0c;find&#xff0c;filter&#xf…

2024年【山东省安全员B证】报名考试及山东省安全员B证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员B证报名考试是安全生产模拟考试一点通生成的&#xff0c;山东省安全员B证证模拟考试题库是根据山东省安全员B证最新版教材汇编出山东省安全员B证仿真模拟考试。2024年【山东省安全员B证】报名考试及山东省…

2024年【山东省安全员A证】最新解析及山东省安全员A证证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 山东省安全员A证最新解析根据新山东省安全员A证考试大纲要求&#xff0c;安全生产模拟考试一点通将山东省安全员A证模拟考试试题进行汇编&#xff0c;组成一套山东省安全员A证全真模拟考试试题&#xff0c;学员可通过…

英语学习交流平台|基于java的英语学习交流平台系统小程序(源码+数据库+文档)

英语学习交流平台系统小程序 目录 基于java的英语学习交流平台系统小程序 一、前言 二、系统设计 三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主介绍&#xff1a;✌️大厂码农|毕设布道师&…

MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例

目录 深入理解 JavaScript 中的 MutationObserver&#xff1a;原理与实战案例 一、MutationObserver 简介 二、MutationObserver 的工作原理 1、基本用法 2、observe 方法的配置项 三、实战案例 案例 1&#xff1a;监控动态内容加载 案例 2&#xff1a;监控属性变化 案…