Linux守护进程揭秘-无声无息运行在后台


在Linux系统中,有一些特殊的进程悄无声息地运行在后台,如同坚实的基石支撑着整个系统的运转。它们就是众所周知的守护进程(Daemon)。本文将为你揭开守护进程的神秘面纱,探讨它们的本质特征、创建过程,以及如何重定向它们的输入输出。通过C++代码示例,你将领略到守护进程背后的编程哲学。


一、守护进程简介


守护进程顾名思义,就是在系统后台默默守护的进程。它们通常在系统启动时创建,并一直运行至系统关闭,生命周期非常长。常见的守护进程包括cron调度器、SSH服务器(sshd)、Redis数据库、Nginx Web服务器等。

守护进程有两个主要特点:

  1. 在后台运行,没有控制终端。因此内核永远不会为它们生成任何与终端相关的信号,如SIGINT(中断)、SIGTSTP(停止)等。
  2. 不受父进程影响。当创建守护进程时,会让出与父进程的关联,成为一个独立的进程组。

根据这一特性,某些守护程序会将SIGINT和SIGHUP信号视为一种通知机制。

如果守护程序接收到这两个信号,这通常意味着信号是由用户或服务本身触发的。


例如,在nginx中,当我们执行nginx -s reload命令以热更新配置文件时,实际上是向nginx的主进程发送了一个SIGHUP信号。

此外,在Linux系统中,也有一些特定的守护进程以线程的方式运行,例如pdflush,它会定期将缓冲区中的数据刷新到磁盘。


守护进程本质上是一个孤儿进程,其父进程在执行fork()之后会立即终止。因此,守护进程最终会被init进程所收养。同时,孤儿进程本身并没有害处。


二、创建守护进程的过程


在Linux系统中,创建一个守护进程通常遵循一个固定的模板,其过程相对标准化,很难省略其中的任何步骤。


创建守护进程的步骤基本如下:

  1. 分身:父进程fork出子进程,然后父进程退出。

    • 执行一个fork(),创建出子进程之后父进程退出,子进程继续执行,如果守护进程是从shell 中创建的,那么守护进程应该让出终端控制,不能占用。
    • 子进程一定不会作为一个进程组的首进程,才有可能释放与当前终端的所有关联。
  2. 开启新会话:子进程调用setsid()脱离所有终端,创建新会话。

    • 一般情况下,终端下直接运行的进程当终端被关闭时,运行的进程也会退出执行
    • 调用成功后终端是否被关闭将不会影响到子进程的运行。
  3. 更改工作目录:防止意外占用目录。

  4. 重置umask:确保有创建文件/目录的权限。

  5. 关闭已打开文件描述符:包括标准输入/输出/错误,防止影响后续程序运行。

    • 因为标准输入、标准输出以及标准错误和终端相关,而我们的守护进程和任何终端都不产生联系,留着这
3 个文件描述符完全没有必要。
    • 但是我们又不能直接关闭掉这
3 个文件描述符,万一程序在某个地方执行了 printf(),那么就会出现错误。
  6. 重定向标准输入/输出/错误:为日志等做准备。

  7. 处理信号:决定如何响应常见信号。


下面是一段简单的代码,演示了创建守护进程的基本流程:

#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

void daemonize() {
    // 分身,父进程退出
    pid_t pid = fork();
    if (pid < 0) exit(EXIT_FAILURE);
    if (pid > 0) exit(EXIT_SUCCESS);

    // 子进程继续,开启新会话
    if (setsid() < 0) exit(EXIT_FAILURE);

    // 更改工作目录
    chdir("/");

    // 重置umask
    umask(0);

    // 关闭已打开文件描述符
    for (int i = sysconf(_SC_OPEN_MAX); i >= 0; i--) {
        close(i);
    }

    // 重定向标准输入/输出/错误
    open("/dev/null", O_RDWR);
    dup(0);
    dup(0);
}

int main() {
    daemonize();

    // 守护进程主循环
    while (1) {
        sleep(1);
        std::cout << "Daemon running..." << std::endl;
    }

    return 0;
}

三、输入输出重定向


在这里插入图片描述


你可能已经注意到,上面的代码中我们重定向了守护进程的标准输入/输出/错误流。这是因为终端关闭时,如果进程还持有这些文件描述符,就会收到SIGHUP信号而退出。而我们的守护进程并不希望如此。


重定向的方式是先打开/dev/null(空设备文件),然后使用dup2()系统调用,将标准输入/输出/错误流的文件描述符指向这个空文件。之后守护进程所有的输入输出都将被丢弃,不会影响到正常运行。


在程序内,如果我们想要将
STDIN_FILENO、STDOUT_FILENO 以及
STDERR_FILENO 这
3 个描述符重定向到
/dev/ null 的话,就需要借助
dup2() 这一系统调用 。


int fd = open("/dev/null", O_RDWR);
dup2(fd, STDIN_FILENO);  
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);

如果我们把文件描述符看作是指针的话,那么
dup2(A,
B) 的作用就是把
A
指向的东西给到
B,让
B的指向和
A
的指向相同。


四、守护万象更新潮流


守护进程作为Linux系统不可或缺的一员,扮演着重要的角色。从上世纪90年代开始,守护进程编程的理念就根深蒂固,影响着整个Linux生态的发展。然而,近年来随着容器和微服务的兴起,传统的守护进程模式也面临着一些挑战和质疑。守护进程的未来将如何演进?它们是否会被新技术所取代?这些都将是值得我们继续关注和探讨的话题。而无论形式如何变迁,稳定、高效、隐身于后台的设计思想,必将patrimony代代相传。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有待挖掘的金矿:大模型的幻觉之境

人工智能正在迅速变得无处不在&#xff0c;在科学和学术研究中&#xff0c;自回归的大型语言模型&#xff08;LLM&#xff09;走在了前列。自从LLM的概念被整合到自然语言处理&#xff08;NLP&#xff09;的讨论中以来&#xff0c;LLM中的幻觉现象一直被广泛视为一个显著的社会…

记录汇川:红绿灯与HMI-ST

项目要求&#xff1a; 子程序&#xff1a; 子程序&#xff1a; 实际动作如下&#xff1a; 红绿灯与HMI-ST

电赛报告书写

一、总体要求 &#xff08;1&#xff09;摘要&#xff1a;一页&#xff0c;小于300字 &#xff08;2&#xff09;正文&#xff1a;不超过8页 &#xff08;3&#xff09;附录&#xff1a;可以没有&#xff0c;但是不能超过2页 二、摘要书写 摘要要小于等于300字&#xff0c…

牛客java基础(一)

A 解析 : java源程序只允许一个public类存在 &#xff0c;且与文件名同名 ; D hashCode方法本质就是一个哈希函数&#xff0c;这是Object类的作者说明的。Object类的作者在注释的最后一段的括号中写道&#xff1a;将对象的地址值映射为integer类型的哈希值。但hashCode()并不…

【Text2SQL 论文】C3:使用 ChatGPT 实现 zero-shot Text2SQL

论文&#xff1a;C3: Zero-shot Text-to-SQL with ChatGPT ⭐⭐⭐⭐ arXiv:2307.07306&#xff0c;浙大 Code&#xff1a;C3SQL | GitHub 一、论文速读 使用 ChatGPT 来解决 Text2SQL 任务时&#xff0c;few-shots ICL 的 setting 需要输入大量的 tokens&#xff0c;这有点昂贵…

【C语言】05.数组

一、数组的概念 本文来介绍数组&#xff0c;首先我们需要了解数组是什么&#xff1f; 数组是⼀组相同类型元素的集合。 • 数组中存放的是1个或者多个数据&#xff0c;但是数组元素个数不能为0。 • 数组中存放的多个数据&#xff0c;类型是相同的。 数组分为⼀维数组和多维数组…

自用的2个chatpgt plus拼车渠道!!!

两个渠道&#xff0c;银河和环球&#xff0c;各有优劣 由于平台限制&#xff0c;链接和优惠码&#xff0c;可看原文 原文&#xff1a;https://www.aiutools.fun/archives/4978 先说结论 gpt重度用户&#xff1a;一天50次以上&#xff0c;选 环球 gpt轻度用户&#xff1a;一天用…

有关大学的搜题软件?六个不限次的公众号和软件分享啦 #其他#职场发展

有些同学虽然喜欢刷题&#xff0c;但是如果参考答案遗失、找不到参考答案&#xff0c;导致做好的题目无法校对&#xff0c;就会比较烦恼了。不过不用担心&#xff0c;今天就给大家分享一些超好用的搜题工具 1.彩虹搜题 这是个老公众号了 它不仅可以查到大学题目&#xff0c;…

Unity3D入门基础知识汇总

1. unity界面 右上边可以切换布局。 左边选择Shaded wireframe&#xff0c;可以看到3D物体的都是由三角形组成的。 2. 物体显示 网格&#xff08;三角形构成&#xff09; 材质 3. 资源商店 Windows -> Asset Store 挑出喜欢的资源之后&#xff0c;点击”添加至我的…

Qwen-VL论文阅读

论文地址 其他同学的详细讲解 模型结构和参数大小 &#xff08;1&#xff09;LLM&#xff1a;Qwen-7B &#xff08;2&#xff09;Vision Encoder&#xff1a;ViT架构&#xff0c;初始化参数是 Openclip’s ViT-bigG。 在训练和推理过程中&#xff0c;输入的图像都被调整到…

git(其六)--总结

配置基础信息 //1.配置用户名和邮箱 git config --global user.name "带着引号写一个昵称" git config --global user.email "带着引号写一个邮箱"//2.建立一个git本地库 git init//3.查看本地内容 git status //可以看到那些处于待加入本地库的文件&a…

​​​​​​ 基于Nmap的异步无状态端口扫描技术

​​​​​​ 基于Nmap的异步无状态端口扫描技术 传统的端口扫描&#xff0c;主要是依靠TCP三次握手去连接&#xff0c;而建立连接的各个过程都存在连接状态&#xff0c;这些状态由操作系统在底层实现存储&#xff0c;可利用这些状态对应用层的数据进行处理。但是&#xff0c;…

【Flutter】 TextField限制长度时, 第三方手写输入法、ios原始拼音输入法输入被吞问题

问题描述 TextField限制长度时&#xff0c; 当你的输入字符长度已经到了最大值-1时&#xff0c;使用第三方手写输入法或者ios原生拼音输入法输入liang&#xff08;什么拼音都行&#xff0c;这里只是举例&#xff09;&#xff0c;输到i那么li都会消失。 原因分析 这是因为第三…

[论文笔记]AIOS: LLM Agent Operating System

引言 这是一篇有意思的论文AIOS: LLM Agent Operating System&#xff0c;把LLM智能体(代理)看成是操作系统。 基于大语言模型(LLMs)的智能代理的集成和部署过程中存在着许多挑战&#xff0c;其中问题包括代理请求在LLM上的次优调度和资源分配&#xff0c;代理和LLM之间在交互…

苹果将推出“Apple Intelligence”AI系统,专注于隐私和广泛应用|TodayAI

据彭博社报道,苹果公司将在下周的 WWDC 2024 开发者大会上揭晓其全新的 AI 系统——“Apple Intelligence”,该系统将适用于 iPhone、iPad 和 Mac 设备。这一新系统将结合苹果自身技术和 OpenAI 的工具,为用户提供一系列新的 AI 功能,同时重点关注隐私保护和广泛应用。 与…

如何在virtualbox上安装Linux系统(centerOS)

提示&#xff1a;共同学习 注意&#xff1a;一定要在BIOS中的虚拟化打开。 文章目录 第一步&#xff1a; 第一步&#xff1a; 启动 、显示开启 centos基础安装 ​ ​

MongoDB CRUD操作:地理位置查询

MongoDB CRUD操作&#xff1a;地理位置查询 文章目录 MongoDB CRUD操作&#xff1a;地理位置查询地理空间数据GeoJSON对象传统坐标对通过数组指定&#xff08;首选&#xff09;通过嵌入文档指定 地理空间索引2dsphere2d 地理空间查询地理空间查询运算符地理空间聚合阶段 地理空…

【Linux】The server quit without updating PID file的几种解决方案

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。 &#x1f913; 同时欢迎大家关注其他专栏&#xff0c;我将分享Web前后端开发、人工智能、机器学习、深…

Qt之QGraphicsView —— 笔记3:矩形图元连接(附完整源码)

效果 完整源码 注意:在ui文件中拖入一个QGraphicsView类窗口控件,然后用MyGraphicsView提升该类。 main.cpp #include "widget.h" #include <QApplication>int main(

【Java毕业设计】基于JSP+SSM的物流管理系统

文章目录 目 录摘要ABSTRACT1 概述1.1 课题背景及意义1.2 国内外研究现状1.3 本课题主要工作 2 系统开发环境2.1 JSP技术2.2 JavaScript2.3 B/S结构2.4 HTML简介 3 系统分析3.1 可行性分析3.1.1 技术可行性3.1.2操作可行性3.1.3 经济可行性3.1.4 法律可行性 3.2系统流程设计3.2…