在 Linux 中,守护进程(Daemon)通常是后台运行、无终端、生命周期长的进程。下面从概念 → 常见实现方式 → 推荐做法给你一个完整说明。
守护进程一般具备以下特点:
init / systemd(PID 1)/dev/null示例:
ps -ef | grep nginx
通过以下步骤脱离终端:
fork() 创建子进程setsid() 创建新会话fork()(可选)#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
void daemonize() {
pid_t pid;
pid = fork();
if (pid < 0) exit(1);
if (pid > 0) exit(0); // 父进程退出
setsid(); // 创建新会话
pid = fork();
if (pid < 0) exit(1);
if (pid > 0) exit(0); // 再次 fork
chdir("/"); // 改变工作目录
umask(0); // 重置文件权限掩码
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);
}
int main() {
daemonize();
while (1) {
sleep(10);
}
}
./my_program &
或
nohup ./my_program > app.log 2>&1 &
⚠️ 缺点:
sudo vim /etc/systemd/system/mydaemon.service
[Unit]
Description=My Daemon
After=network.target
[Service]
ExecStart=/usr/local/bin/mydaemon
Restart=always
User=myuser
WorkingDirectory=/usr/local/bin
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start mydaemon
sudo systemctl enable mydaemon
sudo systemctl status mydaemon
✅ 优点:
sudo apt install supervisor
配置:
[program:mydaemon]
command=/usr/local/bin/mydaemon
autostart=true
autorestart=true
stdout_logfile=/var/log/mydaemon.log
| 方式 | 是否推荐 | 说明 |
|---|---|---|
| fork + setsid | ❌ | 底层原理,现代很少手写 |
| nohup + & | ⚠️ | 临时测试 |
| systemd | ✅✅✅ | 生产环境首选 |
| supervisor | ✅ | 多进程管理 |
sshdnginxcrondockerdps -ef | grep mydaemon
守护进程通常:
1?)如果你愿意,可以告诉我:
我可以给你完全可复制的配置示例。