本文目录导读:

- 使用标准库
Daemon(推荐)——统一身份认证服务守护 - 手动实现守护进程(不依赖第三方库)
- 使用
supervisor管理进程(最实用) - 使用
subprocess+ 信号处理(适合简单监控) - 最佳实践建议
在Python中实现进程守护(守护进程)有多种方法,根据需求不同可以选择不同的解决方案,以下是几种常见且实用的实现方式:
使用标准库 Daemon(推荐)——统一身份认证服务守护
python-daemon 是最常用的进程守护库。
安装
pip install python-daemon
示例:文件监控守护进程
import daemon
import time
import os
import logging
import sys
# 日志配置
logging.basicConfig(
filename='/var/log/mydaemon.log',
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
# 自定义工作函数
def run_worker():
while True:
# 模拟工作——检查某个文件的变化
current_time = time.strftime("%Y-%m-%d %H:%M:%S")
logging.info(f"守护进程正在运行,时间: {current_time}")
# 这里放实际的工作逻辑
# 比如检查文件、监控进程、处理数据等
time.sleep(10)
# 守护进程上下文
def start_daemon():
# 设置工作目录、PID文件、日志等
with daemon.DaemonContext(
working_directory='/opt/mydaemon',
umask=0o002,
pidfile=daemon.pidfile.TimeoutPIDLockFile('/var/run/mydaemon.pid'),
stdout=sys.stdout,
stderr=sys.stderr
):
run_worker()
if __name__ == '__main__':
start_daemon()
手动实现守护进程(不依赖第三方库)
import os
import sys
import time
import logging
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
"""完全分离进程并转为守护进程"""
# 第一步:fork并退出父进程
try:
pid = os.fork()
if pid > 0:
sys.exit(0) # 父进程退出
except OSError as e:
sys.stderr.write(f"fork #1 失败: {e}\n")
sys.exit(1)
# 分离子进程与父进程的控制终端
os.setsid()
os.umask(0o22)
# 第二步:再次fork确保进程不会重新获得终端
try:
pid = os.fork()
if pid > 0:
sys.exit(0)
except OSError as e:
sys.stderr.write(f"fork #2 失败: {e}\n")
sys.exit(1)
# 重定向标准文件描述符
stdin = open(stdin, 'r')
stdout = open(stdout, 'a+')
stderr = open(stderr, 'a+')
os.dup2(stdin.fileno(), 0)
os.dup2(stdout.fileno(), 1)
os.dup2(stderr.fileno(), 2)
# 关闭文件描述符
for fd in range(3, 256):
try:
os.close(fd)
except OSError:
pass
# 实际的守护进程工作类
class MyDaemon:
def __init__(self, pidfile):
self.pidfile = pidfile
def run(self):
while True:
# 工作逻辑
with open('/tmp/daemon_status.log', 'a') as f:
f.write(f"守护进程运行中: {time.ctime()}\n")
time.sleep(10)
def start(self):
# 检查是否已有PID文件
if os.path.exists(self.pidfile):
with open(self.pidfile, 'r') as f:
pid = int(f.read())
if os.path.exists(f'/proc/{pid}'):
print("进程已在运行中")
return
daemonize('/dev/null', '/tmp/daemon_stdout.log', '/tmp/daemon_stderr.log')
# 写PID文件
with open(self.pidfile, 'w') as f:
f.write(str(os.getpid()))
self.run()
def stop(self):
if os.path.exists(self.pidfile):
with open(self.pidfile, 'r') as f:
pid = int(f.read())
os.kill(pid, 15) # 发送SIGTERM
os.remove(self.pidfile)
print(f"已停止进程 {pid}")
else:
print("进程未运行")
# 使用示例
if __name__ == '__main__':
daemon = MyDaemon('/tmp/mydaemon.pid')
if len(sys.argv) != 2:
print("用法: python daemon.py [start|stop|restart]")
sys.exit(1)
action = sys.argv[1]
if action == 'start':
daemon.start()
elif action == 'stop':
daemon.stop()
elif action == 'restart':
daemon.stop()
time.sleep(1)
daemon.start()
else:
print(f"未知命令: {action}")
使用 supervisor 管理进程(最实用)
虽然supervisor不是纯Python实现,但它是最常用的进程管理系统:
配置 supervisord
# /etc/supervisor/conf.d/myapp.conf [program:myapp] command=python /opt/myapp/main.py directory=/opt/myapp user=www-data autostart=true autorestart=true startretries=3 stderr_logfile=/var/log/myapp.err.log stdout_logfile=/var/log/myapp.out.log
Python代码(无需特殊处理)
# main.py
import time
import logging
logging.basicConfig(level=logging.INFO)
def main():
while True:
logging.info("应用正在运行...")
time.sleep(10)
if __name__ == '__main__':
main()
使用 subprocess + 信号处理(适合简单监控)
import subprocess
import signal
import os
import sys
import time
class ProcessGuardian:
def __init__(self, command):
self.command = command
self.process = None
self.running = True
def start_process(self):
print(f"启动进程: {self.command}")
self.process = subprocess.Popen(
self.command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
def monitor(self):
# 设置信号处理
signal.signal(signal.SIGINT, self.handle_exit)
signal.signal(signal.SIGTERM, self.handle_exit)
while self.running:
# 检查进程状态
if self.process.poll() is not None:
print(f"进程退出,代码: {self.process.returncode}")
self.start_process() # 自动重启
time.sleep(5)
def handle_exit(self, signum, frame):
print("收到退出信号...")
self.running = False
if self.process:
self.process.terminate()
sys.exit(0)
if __name__ == '__main__':
guardian = ProcessGuardian("python worker.py")
guardian.start_process()
guardian.monitor()
最佳实践建议
- 生产环境首选:使用
supervisor或systemd管理,简单可靠 - 纯Python方案:使用
python-daemon库 - 需要PID控制:手动实现守护进程 + PID文件管理
- 简易监控:使用
subprocess守护另一个进程
选择哪种方式取决于你的具体需求、部署环境和团队技术栈,对于大多数Python Web应用和微服务,推荐使用 supervisord 或 systemd 进行进程管理。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播