用 os.setsid() 脱离进程组,systemd 配置 delegate=yes 和 killmode=process,文件系统(json+os.replace)共享数据,pid 文件或健康端点判断服务状态,日志加前缀区分。

Python 脚本怎么不被服务进程 kill 掉
服务进程(比如用 systemd 或 supervisord 管理的后台服务)默认会把子进程设为同一进程组,脚本一启动就被父服务收编,服务重启/停止时连带干掉——这不是脚本写得有问题,是进程生命周期没切开。
- 用
os.setsid()在脚本开头新建会话,脱离父进程组:import os os.setsid() # 必须在 fork 后、exec 前调用,单进程脚本可直接用
- 避免使用
subprocess.run(..., shell=True)启动长期任务,它默认继承父环境;改用start_new_session=True参数 - 如果脚本由
systemd启动,加配置项Delegate=yes和KillMode=process,否则 systemd 会递归杀光所有子进程
脚本和服务共享数据但不共享内存怎么办
Python 多进程间不能直接传对象引用,尤其服务是常驻进程、脚本是临时任务时,靠全局变量或模块级变量根本不可靠。
- 优先走文件系统:用
json+ 原子写入(os.replace())做状态快照,服务轮询读取,脚本写完就退出 - 避免用
sqlite3的 WAL 模式做高并发读写,小规模没问题,但脚本频繁启停容易留下-wal文件卡住服务 - 别碰
multiprocessing.Manager—— 它依赖本地 socket,脚本和服务不在同一 Python 进程树里时根本连不上,报错是ConnectionRefusedError
如何让脚本感知服务是否还在运行
脚本需要判断服务状态再决定是否执行,但不能靠 ps aux | grep 这种脆弱方式——进程名可能重复,权限可能不够,还容易漏判。
Destoon B2B网站管理系统是一套完善的B2B(电子商务)行业门户解决方案。系统基于PHP+MySQL开发,采用B/S架构,模板与程序分离,源码开放。模型化的开发思路,可扩展或删除任何功能;创新的缓存技术与数据库设计,可负载千万级别数据容量及访问。 系统特性1、跨平台。支持Linux/Unix/Windows服务器,支持Apache/IIS/Zeus等2、跨浏览器。基于最新Web标准构建,在
- 服务启动时写一个带时间戳的 pid 文件,路径统一设为
/var/run/myapp/service.pid,脚本读它后用os.kill(pid, 0)检查进程是否存在 - 更稳的是走服务暴露的健康端点:比如服务开了
http://127.0.0.1:8000/health,脚本用requests.get()加超时(timeout=2),失败就当服务离线 - 注意不要在脚本里用
time.sleep(5)等服务启动,systemd 有After=,supervisord 有startsecs,交给进程管理器处理依赖
日志混在一起看不清谁干了什么
服务和脚本都往 stdout 打日志,systemd journal 里全搅成一团,grep ERROR 时分不清是服务崩溃还是脚本参数错了。
立即学习“Python免费学习笔记(深入)”;
- 脚本必须加前缀:用
logging.basicConfig(format='[script] %(message)s'),服务端同理用[service] - 别依赖
print(),它不经过 logging handler,systemd 里可能缓冲延迟输出;一律走logging.info() - 如果脚本执行很快(StandardOutput=append:/var/log/myapp/script.log 单独落盘更可控
事情说清了就结束。最常被忽略的是进程组隔离和日志前缀——其他都能绕,这两点一漏,排查成本直接翻倍。









