subprocess - 当父 python 脚本被 systemd 停止时子进程退出
问题描述
我是 python 新手,想熟悉一下,所以我创建了一个 python 脚本,它使用子进程中的 Popen 来执行 bash 脚本。bash 脚本设置环境并执行 c++ 程序以在后台运行。
预期用途是将 python 脚本作为监视 C++ 进程的服务运行,如果 C++ 进程退出,则再次运行 bash 启动脚本。
如果我从命令行 ( ./proc_watchdog.py
) 启动 python 脚本,然后按 ctr+c,一切都会按预期运行,C++ 进程将继续运行。
如果我然后使用 systemd 执行 python 脚本,systemd start pythonscript.service
然后停止它systemd stop pythonscript.service
,C++ 程序就会退出。
.service 文件:
[Unit]
Description=RustDedicated watchdog service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=scriptuser
ExecStart=/path/to/C++_Prog_Dir/proc_watchdog.py
[Install]
WantedBy=multi-user.target
蟒蛇脚本:
#!/usr/bin/python3
import subprocess as sp
import os
import psutil
import time
backgroundProc = "Procname"
def processWatchdog():
waitCount = 0;
while True:
procList = []
for proc in psutil.process_iter():
procList.append(proc.as_dict(attrs=['name']))
found = 0
for pname in procList:
if backgroundProc == pname['name']:
print("Process running")
found = 1
if found == 0:
print("Process not found...")
waitCount += 1
if waitCount == 3:
p = sp.Popen(["/path/to/C++_Prog_Dir/start.sh"])
print("Restarting")
p.wait()
waitCount = 0
print("Restarted")
time.sleep(2)
if __name__ == '__main__':
processWatchdog()
Bash 脚本示例:
#!/bin/bash
./c++_process &>> /dev/null &
exit 0
谁能帮我理解为什么 python 脚本在每种执行方式下的行为都会不同?
解决方案
做适当的监督让父母等待孩子。当孩子退出时,重新启动它。这就是 DJB 的 daemontools 所做的。
更改您的脚本:
./c++_process &>> /dev/null &
至:
exec ./c++_process &>> /dev/null
然后,您的看门狗将在p.wait()
返回时立即收到警报,因为它必须重新启动程序,因为它已经退出。这样,您的看门狗就可以简化为:
import subprocess as sp
import time
def processWatchdog():
while True:
p = sp.Popen(["/path/to/C++_Prog_Dir/start.sh"])
p.wait()
time.sleep(2)
if __name__ == '__main__':
processWatchdog()
这只是以 2 秒的延迟重新启动程序。
推荐阅读
- javascript - 减慢滚动顶部jquery
- android - 当我以编程方式更改我的应用程序语言时,如何保护我的应用程序用户界面发生变化?
- node.js - 重建家园时出现 npm 符号链接错误
- .htaccess - htaccess 将 example.com/about 重定向到 https://www.example.com/about
- java - 如何在返回带有条件的布尔值的方法上使用流
- android - Android:如何以设备所有者身份通过设备策略管理器禁用播放保护?
- r - prop.test,以其他类为条件
- laravel - Laravel RegisterController 路由未找到
- mips - 如何为 MIPS 中的指令设置内存地址?
- c# - 使用 Automapper 时如何忽略特定类型的属性?