python第三方库/python-daemon/将当前进程变为守护进行
守护进程
什么是守护进程?
守护进程是一种在后台运行的进程,通常用于执行周期性或长时间运行的任务。
特点:
- 在后台运行的进程
- 没有控制终端(不受键盘、tty影响)
守护进程的原始实现
- 守护进程实现核心步骤
- fork() 一个子进程,父进程退出(脱离原始终端)
- setsid() 创建新会话,脱离控制终端
- 第二次 fork() 防止重新获得终端
- chdir(‘/‘) 切换到根目录(避免锁定工作目录)
- umask(0) 重设文件权限掩码
- 重定向 stdin、stdout、stderr 到 /dev/null
- 守护进程实现核心步骤
实现守护进程的方法
方法1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import os
import sys
def daemonize():
# 第一次 fork
pid = os.fork()
if pid > 0:
sys.exit(0)
# 脱离终端,创建新会话
os.setsid()
os.umask(0)
# 第二次 fork,避免重新打开终端
pid = os.fork()
if pid > 0:
sys.exit(0)
# 关闭标准文件描述符并重定向到 /dev/null
sys.stdout.flush()
sys.stderr.flush()
with open('/dev/null', 'rb', 0) as f:
os.dup2(f.fileno(), sys.stdin.fileno())
with open('/dev/null', 'ab', 0) as f:
os.dup2(f.fileno(), sys.stdout.fileno())
os.dup2(f.fileno(), sys.stderr.fileno())方法2(推荐使用)
1
2
3
4
5
6
7
8
9import daemon
def run():
while True:
# 你的后台任务代码
...
with daemon.DaemonContext():
run()方法3:使用multiprocessing模块
1
2
3
4
5
6
7
8
9
10from multiprocessing import Process, current_process
def task():
process = current_process()
print(f"Daemon process: {process.daemon}")
if __name__ == "__main__":
process = Process(target=task, daemon=True)
process.start()
process.join()
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import time
import daemon
from daemon import pidfile
LOG_PATH = "/tmp/my_daemon.log"
PID_PATH = "/tmp/my_daemon.pid"
def run():
while True:
with open(LOG_PATH, "a") as f:
f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] Daemon is running...\n")
time.sleep(5)
if __name__ == "__main__":
with daemon.DaemonContext(
working_directory=".",
umask=0o002,
pidfile=pidfile.TimeoutPIDLockFile(PID_PATH)
):
run()