当前位置: 首页 > news >正文

【Linux取经路】守护进程

在这里插入图片描述

文章目录

  • 一、前台进程和后台进程
  • 二、Linux 的进程间关系
  • 三、setsid——将当前进程设置为守护进程
  • 四、daemon——设置为守护进程
  • 五、结语

一、前台进程和后台进程

image-20240320212621951

Linux 中每一次用户登录都是一个 session,一个 session 中只能有一个前台进程在运行,键盘信号只能发送给前台进程,其中谁拥有键盘文件谁就是前台进程。./process & 表示启动一个后台进程,后台进程和前台进程可以同时向显示器进行打印。

image-20240320213543544

jobs 查看后台进程。

image-20240320213642676

fg 后台任务号 将一个后台进程提到前台。如果 ctrl+z 将一个前台进程给暂停了,那么操作系统会把 bash 提到前台来,并且把暂停的进程放到后台。在命令行中前台进程一定要存在。bg 后台任务号 将一个因为暂停而被放到后台的任务重新启动,启动后是在后台运行。

二、Linux 的进程间关系

image-20240320220016443

其中 PGID 是进程组 ID,一个任务会对应一个进程组,一个任务可能需要几个进程共同来完成。多个任务(进程组),在同一个 session 内启动的,sid 是一样的,该 sid 其实就是操作系统为该会话所创建的 bashpid

image-20240320222509999

我们在 Xshell 上关闭连接(退出登录)后,操作系统并没有把之前登录创建的 session 全部清理掉,没有把该 session 下的后台进程全部终止掉,但是在其他一些操作系统上,例如 Windows ,它的注销功能,就是把当前 session 中的全部进程全部终止。为了避免出现用户退出后,进程被终止,这里引出守护进程的概念,所谓守护进程,就是该进程自成进程组,自成会话

三、setsid——将当前进程设置为守护进程

#include <unistd.h>pid_t setsid(void);
  • 返回值:成功,返回一个新的 sid,一般都是当前进程的 pid。失败,-1被返回,错误码被设置。
  • 注意:调用该函数的进程不能是某个进程组的组长。而我们一般直接在命令行 ./ 执行的某个可执行文件,都是自成进程组的,自己就是进程组的组长,所以要向实现守护进程,非常重要的一步就是 fork 创建子进程,然后让父进程退出,此时子进程的组 ID 就是父进程的 PID,而不是自己的 PID,此时就可以在子进程中调用 setsid 函数。守护进程的本质也是孤儿进程,它会被操作系统领养,但是它为自己创建了一个新的会话(session),此时就不受任何用户登录和注销的影响。

守护进程的过程分为以下四步

  • 忽略其他异常信号

  • 创建子进程,终止父进程,让子进程成为一个独立的会话

  • 更改当前的工作目录

  • 将标准输入、标准输出、标准错误重定向到 /dev/null (相当于一个垃圾箱,输入进程的东西都被丢弃了,并且从里面获取不到任何输入)

// Daemon.hpp
#include <iostream>
#include <signal.h>
#include <unistd.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>const std::string nullfile = "/dev/null";void Daemon(const std::string &cwd = "")
{// 1. 忽略其他异常信号signal(SIGCHLD, SIG_IGN); // 17号信号——子进程退出给父进程发送这个信号signal(SIGPIPE, SIG_IGN); // 读端关闭写端正常,操作系统会给写端发送13号信号,终止掉写端signal(SIGSTOP, SIG_IGN); // 暂停信号// 2. 创建子进程,将父进程终止,让子进程变成独立的会话if (fork() > 0)exit(0);setsid();// 3. 更改当前的工作目录if (!cwd.empty())chdir(cwd.c_str());// 4. 将标准输入,标准输出,标准错误重定向至 /dev/null(这就相当于一个垃圾箱,输入进去的内容都会被丢弃)int fd = open(nullfile.c_str(), O_RDWR);if(fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}
}

image-20240321101120175

image-20240321102157430

image-20240321103447116

小Tips:一般守护进程的名字都以 d 结尾。

四、daemon——设置为守护进程

daemon 函数是系统为我们提供的将一个进程设置成守护进程的函数。

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

nochdir 为 0 表示将进程的工作目录设置到 / 目录。noclose 表示将标准输入、标准输出、标准错误重定向到 /dev/null 中。

五、结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

在这里插入图片描述

相关文章:

  • vue router中的导航守卫,它的5个使用场景举例
  • 航天科技集团与SPACEX公司的思考与分析
  • vue2+echarts实现简易的2d地图效果
  • 算力巅峰对决,一文读懂CPU、GPU、GPGPU、FPGA、DPU、TPU
  • apache poi 插入“下一页分节符”并设置下一节纸张横向的一种方法
  • Python版本管理器-Miniconda
  • 【Linux】线程(一)
  • 在大数据时代:为何硬盘仍是数据中心存储的核心
  • 基于springboot的人力资源管理系统源码数据库
  • WEB基础--TOMCAT服务器
  • 怎么提高音频的播放速度?提高音频播放速度的四种方法
  • 基于usb通信的鼠标设计
  • Java爬虫——正则表达式应用
  • 超全分析MybatisPlus中的MetaObjectHandler全局字段填充的基本知识(附Demo及实战)
  • 【TensorFlow深度学习】生成对抗网络(GAN)的基本构造与原理
  • 【5+】跨webview多页面 触发事件(二)
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Java 网络编程(2):UDP 的使用
  • Java编程基础24——递归练习
  • Java读取Properties文件的六种方法
  • Odoo domain写法及运用
  • vue 个人积累(使用工具,组件)
  • VuePress 静态网站生成
  • 第十八天-企业应用架构模式-基本模式
  • 工程优化暨babel升级小记
  • 和 || 运算
  • 力扣(LeetCode)56
  • 无服务器化是企业 IT 架构的未来吗?
  • mysql面试题分组并合并列
  • 国内开源镜像站点
  • # 飞书APP集成平台-数字化落地
  • #微信小程序(布局、渲染层基础知识)
  • (1)(1.11) SiK Radio v2(一)
  • (12)Linux 常见的三种进程状态
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (三)终结任务
  • (十五)使用Nexus创建Maven私服
  • (算法设计与分析)第一章算法概述-习题
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)EOS中账户、钱包和密钥的关系
  • (转)LINQ之路
  • .NET C# 使用GDAL读取FileGDB要素类
  • .NET Core 版本不支持的问题
  • .net mvc部分视图
  • .Net 代码性能 - (1)
  • .NET 服务 ServiceController
  • .Net 应用中使用dot trace进行性能诊断
  • .NET框架设计—常被忽视的C#设计技巧
  • .NET连接数据库方式
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • ::
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [18] Opencv_CUDA应用之 基于颜色的对象检测与跟踪