全面理解守护进程的基础概念,以及如何创建一个守护进程(系列文章第三篇)
前言
这个系列的文章有四篇,其目的是为了搞清楚:
进程,shell,shell进程,终端,控制终端,前台进程,后台进程,控制进程,前台进程组,后台进程组,会话,守护进程,init进程,用户进程,系统进程
它们之间的联系与区别- 系列文章第一篇传送门:全面理解shell进程、终端、控制终端的概念,以及它们之间有什么区别与联系?(系列文章第一篇)
- 系列文章第二篇传送门:全面理解进程组,会话的基础概念,以及进程组,会话,控制终端,前台进程组与后台进程组之间的联系(系列文章第二篇)
- 系列文章第四篇传送门:全面理解前台进程,后台进程的概念,以及之间如何切换,init进程与系列文章大总结(系列文章第四篇)
什么是守护进程
守护进程(daemon)是在 Unix 和类 Unix(如 Linux)操作系统中运行的一种特殊的后台进程,它们独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。
-
守护进程通常在系统引导装载时启动,并且在系统关闭之前一直运行。
-
守护进程的名称通常以 "d" 结尾,以便于区分
。例如,sshd 是 Secure Shell 守护进程,httpd 是 HTTP 守护进程。 -
这些进程在后台运行,提供各种服务
,例如处理网络请求(如 web 服务器)、处理系统日志、处理电子邮件和其他各种任务。 -
守护进程通常不直接与用户交互,但它们工作起来非常重要,为其他程序和用户提供关键服务。
-
守护进程在创建时通常会进行“孤儿化”操作,使其成为 init 进程(进程ID为1)的子进程。这样,它们就可以在后台运行,不受任何特定用户或会话的影响。此外,守护进程通常会更改其工作目录到根目录 (“/”),关闭所有已打开的文件描述符(包括输入、输出和错误输出),并重新打开标准输入、标准输出和标准错误到/dev/null,这样就可以防止它们不小心读取或写入任何用户文件或终端。
总的来说,守护进程是一种在后台运行,为系统或其他程序提供服务的进程。
如何创建一个守护进程
创建守护进程需要一定的步骤,这些步骤确保了守护进程能够在后台独立运行,并且不受任何特定用户或会话的影响。
下面我来解释一下每个步骤的含义:
-
执行一个 fork(),之后父进程退出,子进程继续执行。
- 这是创建守护进程的第一步,目的是让守护进程在后台运行。在fork()之后,父进程退出,子进程成为孤儿进程,并被 init 进程(进程ID为1)接管。
-
子进程调用 setsid() 开启一个新会话。
- setsid()函数会创建一个新的会话,并且让子进程成为这个新会话的首进程。这样子进程就与其原来的会话、进程组和控制终端脱离,成为一个新的会话的首进程,可以独立运行。
-
清除进程的 umask 以确保当守护进程创建文件和目录时拥有所需的权限。
- umask是一个权限掩码,它决定了新建文件或目录的默认权限。清除umask是为了让守护进程能够有更大的权限控制它创建的文件或目录。
-
修改进程的当前工作目录,通常会改为根目录(/)。
- 这是为了防止守护进程阻止文件系统被卸载。如果守护进程的工作目录在一个挂载的文件系统中,那么这个文件系统就不能被卸载。
-
关闭守护进程从其父进程继承而来的所有打开着的文件描述符。
- 这是为了避免守护进程继续使用这些文件描述符,可能会导致不可预料的问题。
-
在关闭了文件描述符0、1、2之后,守护进程通常会打开/dev/null 并使用dup2() 使所有这些描述符指向这个设备。
- 这是为了让守护进程的标准输入、输出和错误输出被重定向到/dev/null,避免它们产生任何输出,因为守护进程通常不需要和用户交互。
核心业务逻辑 在完成了以上所有的步骤后,守护进程开始执行其核心的业务逻辑,为系统或其他程序提供服务。
示例:创建一个守护进程
下面是一个简单的守护进程的例子,这个程序会每2秒获取一次系统时间,并写入一个叫做time.txt的文件中
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void daemonize()
{// 执行一个 fork(),之后父进程退出,子进程继续执行。pid_t pid = fork();if (pid > 0)exit(0);else if (pid < 0){perror("fork");exit(0);}// 子进程调用 setsid() 开启一个新会话。if (setsid() == -1){perror("setsid");exit(0);}// 清除进程的 umask 以确保当守护进程创建文件和目录时拥有所需的权限。umask(0);// 修改进程的当前工作目录,通常会改为根目录(/)。chdir("/home/nowcoder/Linux/lession28");// 关闭守护进程从其父进程继承而来的所有打开着的文件描述符。close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);// 在关闭了文件描述符0、1、2之后,守护进程通常会打开/dev/null 并使用dup2() 使所有这些描述符指向这个设备。
}// 代码主体逻辑部分
int main()
{daemonize();FILE *file = fopen("/home/nowcoder/Linux/lession28/time.txt", "a+");if (file == NULL){perror("fopen");exit(0);}while (1){time_t tt = time(NULL);struct tm t = *localtime(&tt);fprintf(file, "现在是北京时间: %d-%d-%d %d:%d:%d\n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);fflush(file); // 保证数据立即写入文件sleep(2);}return 0;
}
- 编译和运行这个程序之后,你可以使用ps -ef | grep a.out(假设你的程序名是a.out)来查看守护进程。你会看到它没有控制终端,而且会话ID是1,这都是守护进程的特征。
- 你可以用
kill - 9 守护进程的进程号
去杀死一个守护进程
注意,这是一个基础的守护进程,一个真实的守护进程可能需要处理更多的细节,对于实际环境中的守护进程,需要处理的问题可能包括但不限于:
-
日志记录:当守护进程运行时,可能需要记录或报告它的行为。通常,它将这些信息写入日志文件或系统日志。
-
配置文件:守护进程通常有一些可配置的设置,这些设置通常存储在配置文件中。当守护进程启动时,它会读取这个配置文件。
-
信号处理:守护进程需要响应系统发送给它的信号。例如,当系统关闭时,它可能会收到一个SIGTERM信号,通知它应当进行清理并优雅地终止。
-
错误处理:守护进程需要处理可能在运行时发生的各种错误,例如文件读取失败、网络连接中断等。
-
权限管理:守护进程可能需要以特定的用户身份运行,以限制其对系统资源的访问。
-
资源管理:如果守护进程创建了子进程,那么它可能需要跟踪这些进程,确保它们被正确地关闭和清理。
以上就是在设计守护进程时,可能需要考虑的一些问题。这些问题的处理方式会因应用的具体需求而异。
如何终止一个守护进程
终止守护进程:
-
使用kill命令:如果你知道守护进程的进程ID(可以通过ps,top,htop或者pgrep命令查找),你可以使用kill命令来发送一个信号终止它,例如kill 12345,其中12345是进程ID。
-
使用pkill或者killall命令:如果你知道守护进程的名字,你可以使用pkill或者killall命令来终止所有名字匹配的进程,例如pkill mydaemon或者killall mydaemon,其中mydaemon是进程名。
系统定义的守护进程与用户自定义的守护进程的区别
-
系统定义的守护进程通常是在系统启动时自动启动的,用于执行一些系统任务,如网络服务、日志记录等。这些守护进程的生命周期通常与系统运行时间相同。
-
用户自定义的守护进程是由用户创建并启动的,通常用于执行特定的任务,如监控某个服务、定期执行一些任务等。这些守护进程的生命周期可能会比系统定义的守护进程短,因为它们可能在任务完成后就终止。
注意,系统定义的守护进程通常是由系统管理员或者root用户启动的,所以只有管理员或者root用户才能终止它们。而用户自定义的守护进程则可以由创建它们的用户来终止
。
总结
-
守护进程(Daemon)是一类在 Unix 和 Unix-like 操作系统中运行的后台进程。这些进程通常在系统启动时开始,然后在系统关闭时结束。守护进程通常不与用户直接交互,它们为其他程序和用户提供服务,例如网络服务、系统日志服务、打印服务等。
-
守护进程的名称通常以 “d” 结尾,这表示它是一个守护进程。例如,httpd 是一个处理 HTTP 请求的守护进程,sshd 是一个提供安全 shell 服务的守护进程。
总的来说,守护进程就是在后台运行,为系统或用户提供各种服务的进程。与普通的进程一样,只要知道进程号,就可以用kill信号去杀死它。
最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容
。
相关文章:

全面理解守护进程的基础概念,以及如何创建一个守护进程(系列文章第三篇)
前言 这个系列的文章有四篇,其目的是为了搞清楚: 进程,shell,shell进程,终端,控制终端,前台进程,后台进程,控制进程,前台进程组,后台进程组&#…...

Leetcode刷题日志5.0
目录 前言: 1.两数相加 2.无重复字符的最长子串 3.整数反转 4.删除链表的倒数第 N 个结点 前言: 今天我又来继续分享最近做的题了,现在开始进入我们快乐的刷题时间吧!(编程语言Python3.0,难度…...

母亲节:向世界上最伟大的母爱致敬
在这世间众多的亲情关系中,有一种关系无与伦比,毫不费力地凌驾于其他任何已知的地球关系之上。这种非凡的关系就是母亲与子女之间的关系。 母亲对家庭无尽的爱、奉献和忠诚使这份感情无价。为了向全球所有母亲表示敬意,母亲节在世界46个国家庆…...

Springboot +Flowable,各种历史信息如何查询(二)
一.简介 正在执行的流程信息是保存在以 ACT_RU_ 为前缀的表中,执行完毕的流程信息则保存在以 ACT_HI_ 为前缀的表中,也就是流程历史信息表。 假设有一个流程,流程图如下: 当这个流程执行完毕后,以 ACT_RU_ 为前缀的…...

DataX下载安装使用
文章目录 01.Clickhouse到HBase(Phoenix)数据导入 DataX介绍下载执行同步的组件配置数据同步查看官方读写配置样例创建Hbase和Phoenix表创建ClickHouse表写入ClickHouse测试数据编写ClickHouse2Hbase配置文件执行同步命令 拓展ClickHouse同步到MySQL配置文件 01.Clickhouse到HB…...

PCB多层板 : 磁通对消法有效控制EMC
在PCB的EMC设计考虑中,首先涉及的便是层的设置;单板的层数由电源、地的层数和信号层数组成;在产品的EMC设计中,除了元器件的选择和电路设计之外,良好的PCB设计也是一个非常重要的因素。 PCB的EMC设计的关键࿰…...

基于正点原子电机实验的pid调试助手代码解析(速度环控制)
这里写目录标题 下位机与PID调试助手传输的原理代码讲解(基于正点原子)解析数据接受和数据发送的底层函数数据接受数据帧格式环形数组以及怎么找到它的帧头位置crc校验 数据发送数据上传函数 通过前两节文章,我已经了解了基本的pid算法,现在在完成了电机…...

报表设计器Stimulsoft 2023.2提供深色主题和 Monoline 图标包
Stimulsoft Reports 是一款报告编写器,主要用于在桌面和Web上从头开始创建任何复杂的报告。可以在大多数平台上轻松实现部署,如ASP.NET, WinForms, .NET Core, JavaScript, WPF, Angular, Blazor, PHP, Java等,在你的应用程序中嵌入报告设计器…...

文本三剑客之——sed编辑器
sed编辑器 sed编辑器sed基础语法sed查询sed删除sed 替换sed 插入 sed编辑器 sed是文本处理工具,依赖于正则表达式,可以读取文本内容,工具指定条件对数据进行添加、删除、替换等操作,被广泛应用于shell脚本,以完成自动…...

华为OD机试真题 Java 实现【贪心的商人】【2023Q1 100分】
一、题目描述 商人经营一家店铺,有number种商品,由于仓库限制每件商品的最大持有数量是item[index],每种商品的价格在每天是item_price[item_index][day],通过对商品的买进和卖出获取利润,请给出商人在days天内能获取到的最大利润。 注:同一件商品可以反复买进和卖出;…...

《数据结构与算法C++版》实验二-链表实验
一、实验内容 实验目的 1、实现线性表的链式存储结构(链表)。 2、熟悉 C++程序的基本结构,掌握程序中的头文件、实现文件和主文件之间的 相互关系及各自的作用。 3、熟悉链表的基本操作方式,掌握链表相关操作的具体实现。 实验内容 对链式存储结构的线性表进行一些基本操作…...

【2023华为OD笔试必会25题--C语言版】《06 简单的自动曝光》——数组
本专栏收录了华为OD 2022 Q4和2023Q1笔试题目,100分类别中的出现频率最高(至少出现100次)的25道,每篇文章包括原始题目 和 我亲自编写并在Visual Studio中运行成功的C语言代码。 仅供参考、启发使用,切不可照搬、照抄,查重倒是可以过,但后面的技术面试还是会暴露的。✨✨…...

Science Advances:宋艳课题组发现经颅近红外激光刺激可提升人类工作记忆
图1. 新闻稿封面 工作记忆——在几秒钟内主动“记住”有用信息的能力——在许多高级认知活动中起着至关重要的作用。由于工作记忆能力的个体差异可以预测流体智力和广泛的认知功能,这使得提高工作记忆能力成为干预和增强的有吸引力的目标。 美国食品及药品管理局声…...

Linux系统crash后定位方法-PCIE举例
crash解释 在Linux操作系统中,"crash"通常是指一种用于分析系统崩溃(crash)的工具或方法。当系统发生崩溃时,可能会产生一些关键信息,如错误日志、内存转储文件等。使用crash工具可以分析这些信息ÿ…...

瑞吉外卖 - 启用与禁用员工账号功能(8)
某马瑞吉外卖单体架构项目完整开发文档,基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成,有需要的胖友记得一键三连,关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料:https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…...

【MySQL】索引
记录MySQL学习笔记,大部分图片来自黑马程序员MySQL教程。 文章目录 概述索引结构BTree为什么InnoDB使用BTree索引结构? 索引分类索引语法SQL性能分析1、查看执行频次2、慢查询日志3、profile详情4、explain执行计划 索引使用最左前缀法则索引失效情况1、…...

JavaScript全解析——express
express 的基本使用 ●express 是什么? ○是一个 node 的第三方开发框架 ■把启动服务器包括操作的一系列内容进行的完整的封装 ■在使用之前, 需要下载第三方 ■指令: npm install express 1.基本搭建 // 0. 下载: npm install express// 0. 导入 const express express()…...

【JavaScript数据结构与算法】字符串类(计算二进制子串)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,也会涉及到服务端(Node.js) 📃个人状态: 在校大学生一枚,已拿多个前端 offer(…...

TCP连接不释放,应用产生大量CLOSE_WAIT状态TCP
一、起源 23年元旦期间,大家都沉浸在一片祥和的过节气氛当中。 “滴滴滴”,这头同事的电话响起,具体说些什么我也没太在意,但见同事接完电话之后展现出了一副懊恼夹杂着些许不耐烦的表情。 我不解问道:“怎么了&…...

Spring基础核心概念理解(常见面试题:什么是IoC?什么是DI?什么是Spring?)
目录 IoC 和 SpringIoC DI Spring IoC 和 SpringIoC IoC是控制反转的意思,它意味着控制权(依赖对象)的反转,将控制权进行反转,它是一种思想. 举个例子,理解一下什么是控制反转 现在有三个对象A,B,C. A的创建依赖于B,B的创建依赖于C,当我们想要创建A的时候创建B,同理也要…...

牛客小白月赛 D.遗迹探险 - DP
题目描述 小Z是一名探险家。有一天,小Z误入了一个魔法遗迹。以下是该遗迹的具体组成: 1. 在 x 轴和 y 轴构成的平面上,满足在 1≤x≤n,1≤y≤m 的区域中(坐标(x,y)表示平面上的第x行的第y列),每个整数坐标 (x,y) 都有…...

前端架构师-week6-require源码解析
require 源码解析——彻底搞懂 npm 模块加载原理 require 的使用场景 加载模块类型 加载内置模块:require(fs)加载 node_modules 模块:require(ejs)加载本地模块:require(./utils)支持文件类型 加载 .js 文件加载 .mjs 文件加载 .json 文件…...

作为 IT 行业的过来人,你有什么话想对后辈说的?
作为 IT 行业的过来人,我想对后辈们说,要不断学习和探索新技术,但同时也要注意保持专注和耐心。在这个快速变化的时代,技术更新换代太快,可能会让人感到焦虑和无助,但只要有耐心并专注于自己所做的事情&…...

表数据编辑(数据库)
目录 一、插入数据 1.插入单个元组: INSERT…VALUES语句 2.插入子查询的结果: INSERT…SELECT语句 3.使用SELECT…INTO语句进行数据插入 二、修改数据 1、数据修改语句:UPDATE 2、修改给定表的所有行 3、基于给定表修改某…...

考虑多能负荷不确定性的区域综合能源系统鲁棒规划(Python代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

RocketMQ整理
RocketMQ在阿里云上的商业版本,集成了阿里内部一些更深层次的功能及运维定制。开源版本,功能上略有缺失,但大体上是一样的。 使用Java开发,便于深度定制。最早叫MetaQ。消息吞吐量虽然依然不如Kafka,但是却比RabbitMQ高很多。在阿里内部,RocketMQ集群每天处理的请求数超过…...

Springboot +Flowable,会签、或签简单使用(二)
一.简介 **会签:**在一个流程中的某一个 Task 上,这个 Task 需要多个用户审批,当多个用户全部审批通过,或者多个用户中的某几个用户审批通过,就算通过。 例如:之前的请假流程,假设这个请假流程…...

将核心交换机配置为NTP服务器
AR配置外源NTP 1.配置ntp <XQ-R1220>sys [XQ-R1220]ntp-service unicast-server 120.25.115.20 #阿里云ntp [XQ-R1220]ntp-service unicast-server 203.107.6.88 #阿里云ntp 2.查看ntp状态 <XQ-R1220>display ntp status clock sta…...

application.properties文件注释
这是一个常用的Spring Boot配置文件 在这里,我们可以配置应用程序的各种属性 服务器端口号 server.port8080 数据库配置 spring.datasource.urljdbc:mysql://localhost:3306/test spring.datasource.usernameroot spring.datasource.password123456 spring.datasou…...

MySql查询报错this is incompatible with sql_mode=only_full_group_by
错误示例 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘yiliaohaocai_new.a.id’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_modeonly_full_group_by 原因 SQL …...