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

【Linux】【守护进程】总结整理

守护进程(Daemon)是运行在后台的进程,通常没有与之关联的控制终端。守护进程在启动后会脱离控制终端,并继续在后台运行,即使用户退出登录或者终端关闭也不会影响它们的运行。守护进程常用于提供网络服务、定期执行任务或监控系统状态等。

b36c18698108474cbdf914b837796543.jpeg

守护进程的特点

  • 无控制终端:守护进程没有控制终端,这意味着它们通常不能接收来自终端的输入或输出。
  • 运行在后台:守护进程在后台运行,即使用户退出登录或关闭终端,守护进程仍然持续运行。
  • 长期运行:守护进程通常设计为长期运行,直到手动停止或系统重启。
  • 自动重启:有些守护进程会在意外终止后自动重启,以确保服务的连续性。

创建守护进程的步骤

创建守护进程通常涉及以下步骤:

  1. 创建子进程:使用fork()创建一个子进程。
  2. 成为会话领导者:在子进程中调用setsid()函数,使子进程成为一个新的会话的领导者,并与控制终端脱离。
  3. 改变当前工作目录:通常将当前工作目录更改为根目录/,以避免由于当前目录被卸载而导致的问题。
  4. 重设文件权限掩码:通常使用umask(0)设置文件权限掩码,这样守护进程创建的文件具有最宽松的权限。
  5. 关闭标准文件描述符:关闭标准输入、输出和错误文件描述符(通常是0、1和2),以防止这些描述符引用到已关闭的终端设备。
  6. 可能的第二次fork:为了确保守护进程不会保留任何进程组ID,有时会再次调用fork(),并在父进程中exit(),这样可以确保子进程不会成为一个作业控制进程。

示例代码

以下是一个简单的守护进程创建示例,使用 C 语言编写:

1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <sys/types.h>
5#include <fcntl.h>
6#include <signal.h>
7#include <sys/stat.h>
8#include <errno.h>
9
10void become_daemon() {
11    pid_t pid;
12    int i;
13
14    // 第一次fork
15    pid = fork();
16    if (pid < 0) {
17        fprintf(stderr, "fork #1 failed: %d (%s)\n", errno, strerror(errno));
18        exit(EXIT_FAILURE);
19    }
20    if (pid > 0) {
21        // 父进程退出
22        exit(EXIT_SUCCESS);
23    }
24
25    // 成为会话领导者
26    if (setsid() < 0) {
27        fprintf(stderr, "setsid failed: %d (%s)\n", errno, strerror(errno));
28        exit(EXIT_FAILURE);
29    }
30
31    // 第二次fork
32    pid = fork();
33    if (pid < 0) {
34        fprintf(stderr, "fork #2 failed: %d (%s)\n", errno, strerror(errno));
35        exit(EXIT_FAILURE);
36    }
37    if (pid > 0) {
38        // 父进程退出
39        exit(EXIT_SUCCESS);
40    }
41
42    // 改变当前工作目录
43    if ((chdir("/")) < 0) {
44        fprintf(stderr, "chdir failed: %d (%s)\n", errno, strerror(errno));
45        exit(EXIT_FAILURE);
46    }
47
48    // 重设文件权限掩码
49    umask(0);
50
51    // 关闭标准文件描述符
52    for (i = 0; i < 3; i++) {
53        close(i);
54    }
55
56    // 打开/dev/null作为新的标准文件描述符
57    open("/dev/null", O_RDWR);
58    dup2(0, 1);
59    dup2(0, 2);
60}
61
62int main() {
63    become_daemon();
64
65    // 守护进程的主要逻辑
66    while (1) {
67        printf("守护进程正在运行...\n");
68        sleep(5);
69    }
70
71    return 0;
72}

注意事项

  • 守护进程应该能够处理信号,特别是SIGTERMSIGHUP信号。SIGTERM通常用于请求守护进程优雅地终止,而SIGHUP通常用于通知守护进程重新加载配置文件。
  • 如果守护进程需要记录日志,通常会将日志写入到一个文件中,而不是标准输出。
  • 守护进程通常需要通过命令行参数或配置文件来接受配置选项。
  • 在某些情况下,守护进程还需要处理SIGCHLD信号,以确保子进程的资源被正确清理。
  • 守护进程应该具有良好的错误处理机制,确保即使在遇到问题时也能稳定运行。

守护进程是操作系统中一个重要的组件,用于提供后台服务和支持功能。理解和掌握如何创建和管理守护进程对于开发系统服务和工具非常重要。

 


http://www.kler.cn/a/382770.html

相关文章:

  • 【Unity】Unity拖拽在Android设备有延迟和卡顿问题的解决
  • springboot集成opencv开源计算机视觉库
  • 【FL0013】基于SpringBoot和微信小程序的机电公司管理信息系统
  • 新160个crackme - 093-kesan
  • 一周模电速成(3) 超详细!入门小白速成!!!
  • RDMA驱动学习(二)- command queue
  • 【AI开源项目】FastGPT - 快速部署FastGPT以及使用知识库的两种方式!
  • hive表内外表之间切换
  • Docker 镜像拉不动?自建 Docker Hub 加速站 解决镜像拉取失败
  • 非凸科技助力第49届ICPC亚洲区域赛(成都)成功举办
  • ELK-ELK基本概念_ElasticSearch的配置
  • 立冬:冬日序曲的温柔启幕
  • Renesas R7FA8D1BH (Cortex®-M85) 存储空间介绍
  • 无人机之飞行管控平台篇
  • Linux查看端口占用及Windows查看端口占用
  • 电话语音机器人,是由哪些功能构成?
  • 通过Django 与 PostgreSQL 进行WEB开发详细流程
  • HTMLCSS:爱上班的猫咪
  • InnoDB 存储引擎<五>undo log, redo log,以及双写缓冲区
  • 服务器开放了mongodb数据库的外网端口,但是用mongodbCompass还是无法连接。
  • go build --gcflags是什么意思, go build后面还可以接哪些选项
  • 荣耀2025秋招面试题:DiT与传统Stable Diffusion的区别
  • 【笔记】自动驾驶预测与决策规划_Part6_不确定性感知的决策过程
  • Spark 中 RDD 的诞生:原理、操作与分区规则
  • 详解Rust标准库:BTreeSet
  • containerd配置私有仓库registry