温馨提示×

怎么写linux守护进程

小樊
38
2026-10-03 14:02:50
栏目: 智能运维

在 Linux 中,守护进程(Daemon)是指在后台运行、与终端无关、生命周期长的进程。下面我从概念 → 手写步骤 → 示例代码 → 常见做法四个方面讲清楚。


一、守护进程的核心特点

  1. 脱离控制终端(不随终端关闭而退出)
  2. 在后台运行
  3. 通常 父进程是 init / systemd(PID 1)
  4. 使用 syslog 记录日志
  5. 通常 /var/run/xxx.pid 保存 PID

二、传统手写守护进程的步骤(POSIX 方式)

标准流程(非常重要)

  1. fork() 创建子进程
  2. 父进程退出
  3. 子进程调用 setsid() 创建新会话
  4. 再次 fork()(可选,防止重新获得终端)
  5. 修改工作目录为 /
  6. 重设文件权限掩码 umask(0)
  7. 关闭标准输入/输出/错误
  8. 使用 syslog 写日志

三、C 语言示例(最经典写法)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>

void daemonize() {
    pid_t pid;

    // 1. fork
    pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0); // 父进程退出

    // 2. 创建新会话
    if (setsid() < 0) exit(1);

    // 3. 再 fork(防止重新打开终端)
    pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0);

    // 4. 改变工作目录
    chdir("/");

    // 5. 重设文件掩码
    umask(0);

    // 6. 关闭标准 IO
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    // 7. 使用 syslog
    openlog("mydaemon", LOG_PID, LOG_DAEMON);
}

int main() {
    daemonize();

    while (1) {
        syslog(LOG_INFO, "daemon is running...");
        sleep(10);
    }

    return 0;
}

编译运行:

gcc daemon.c -o mydaemon
./mydaemon
ps -ef | grep mydaemon

四、更现代的做法(推荐)

✅ 方法 1:使用 daemon() 函数(简化版)

#include <unistd.h>

daemon(0, 0);

不推荐用于生产,但适合简单程序


✅ 方法 2:用 systemd(最推荐)

不需要自己写守护逻辑

示例:/etc/systemd/system/mydaemon.service

[Unit]
Description=My Daemon

[Service]
ExecStart=/usr/local/bin/mydaemon
Restart=always

[Install]
WantedBy=multi-user.target

启用:

systemctl daemon-reload
systemctl start mydaemon
systemctl enable mydaemon

✅ 优点:

  • 自动后台
  • 自动重启
  • 日志由 journald 管理

五、Python 守护进程(简单示例)

import os, sys, time

pid = os.fork()
if pid > 0:
    sys.exit()

os.setsid()
os.chdir("/")
os.umask(0)

while True:
    with open("/tmp/daemon.log", "a") as f:
        f.write("running\n")
    time.sleep(10)

实际项目建议用 python-daemon 库


六、总结建议

场景 推荐方式
学习原理 手写 fork + setsid
简单工具 daemon()
生产环境 systemd
脚本语言 systemd + 普通程序

如果你愿意,我可以:

  • 帮你写一个 完整可运行的守护进程
  • 写成 C / Python / Shell
  • 或写成 systemd 服务模板

你现在的用途是什么?(服务?监控?采集?)

0 踩