温馨提示×

linux c++怎样写守护进程

小樊
45
2026-09-23 09:06:22
栏目: 编程语言

在 Linux 下用 C++ 写守护进程(Daemon),核心目标是:
脱离终端、在后台运行、不受用户登出影响。

下面给你一个标准、可用、可移植的做法(System V 风格)。


一、守护进程的基本步骤

  1. fork() 一次,父进程退出
  2. 调用 setsid() 创建新会话
  3. 再次 fork()(可选,防止重新获得终端)
  4. 修改工作目录(通常 /)
  5. 重设文件权限掩码 umask
  6. 关闭 / 重定向标准输入、输出、错误

二、最小可运行 C++ 示例

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

void daemonize() {
    pid_t pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0);   // 父进程退出

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

    // 再 fork 一次(可选)
    pid = fork();
    if (pid < 0) exit(1);
    if (pid > 0) exit(0);

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

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

    // 关闭标准输入输出
    close(STDIN_FILENO);
    close(STDOUT_FILENO);
    close(STDERR_FILENO);

    // 重定向到 /dev/null
    open("/dev/null", O_RDONLY);
    open("/dev/null", O_WRONLY);
    open("/dev/null", O_WRONLY);
}

int main() {
    daemonize();

    while (true) {
        // 守护进程逻辑
        sleep(10);
    }

    return 0;
}

三、更推荐的方式(systemd)

现代 Linux 不建议手写守护进程,而是:

  • 写一个普通程序
  • 用 systemd 管理后台运行

示例 service 文件

[Unit]
Description=My C++ Daemon

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

[Install]
WantedBy=multi-user.target
systemctl enable mydaemon
systemctl start mydaemon

✅ 优点:

  • 自动重启
  • 日志管理(journalctl)
  • 不需要自己处理信号、终端

四、常见坑

问题 说明
仍有终端输出 没重定向 stdin/stdout/stderr
用户退出程序死 没 setsid()
无法写日志 没 chdir 或权限问题
僵尸进程 没处理 SIGCHLD

五、建议

  • 学习 / 了解原理 → 手写 daemon
  • 真实项目 → 用 systemd
  • C++ 项目 → 可配合 boost::process / fork

如果你愿意,我可以:

  • 写一个 带日志的守护进程
  • 写一个 systemd 完整示例
  • 或解释 为什么第二次 fork 不是必须

你想往哪方面深入?

0 踩