killmode=mixed是合法值,非multi;它使主进程收sigterm优雅退出,子进程被立即sigkill终止,防止僵尸进程。

KillMode=multi 并非 systemd 的合法值,正确写法是 KillMode=mixed。它专为需要区分对待主进程与子进程的场景设计:主进程接收 SIGTERM 优雅退出,所有子进程则被立即 SIGKILL 终止,从而避免子进程因父进程已退出却无人回收而变成僵尸。
mixed 模式的核心行为逻辑
当执行 systemctl stop myservice 时:
- systemd 向主进程(MainPID)发送
SIGTERM - 同时向该服务 cgroup 内**除主进程外的所有其他进程**发送
SIGKILL - 主进程有机会在被杀前完成清理、关闭连接或触发子进程退出
- 子进程不会滞留等待 wait(),也不会因父进程先死而被 init 接管后长期不回收
适用场景与配置要点
该模式特别适合以下情况:
- 主进程是 shell 脚本或 Python 程序,内部用
subprocess.Popen()或os.system()启动了长期运行的后台子任务 - 主进程本身不 fork,但依赖外部工具(如
ffmpeg、java -jar)作为工作子进程 - 你希望主进程能响应 TERM 做日志 flush、socket 关闭等,但又不能容忍子进程残留
配置示例(/etc/systemd/system/myworker.service):
Python Linux版 为 Python.org 官方提供的 Python 3.14.6 Linux/Unix 源码包,适合在Linux/Unix环境中安装、运行 Python 代码并学习函数、模块和脚本开发。
[Service] Type=simple ExecStart=/usr/local/bin/worker-launcher.sh KillMode=mixed TimeoutStopSec=30
为什么 mixed 能防僵尸,而 control-group 有时不能?
KillMode=control-group(默认)会同时杀死主进程和全部子进程,看似彻底,但存在风险:
- 若子进程正在执行关键 IO(如写入数据库日志),被强制 kill 可能导致数据不一致
- 若主进程恰好在调用
waitpid()的瞬间被杀,子进程退出状态可能未被读取,短暂变为僵尸 - 某些程序在收到 SIGKILL 后无法释放资源,反而留下更多残留
mixed 把控制权交还给主进程——它可主动 wait() 所有子进程,或向它们发信号并等待其自然退出,确保退出状态被及时回收。
配套建议:强化主进程的子进程管理
仅靠 KillMode=mixed 不够,主进程自身也需配合:
- 在代码中注册
SIGCHLD信号处理器,调用waitpid(-1, WNOHANG)循环回收已退出子进程 - 避免使用
system()或未加wait的fork();改用带超时的subprocess.run()或显式wait() - 若使用 shell 脚本启动,可在脚本末尾添加
wait,并确保子进程未被&脱离前台组










