背景:
我有一个C#程序,我在Linux(特别是Raspbian)的Mono下运行。我正在研究一个Python脚本,该脚本启动该程序,对其进行监视并优雅地将其杀死。我使用subprocess.Popen
在mono下运行C#程序。当我正常运行Python时,我可以向进程发送一个SIGINT
,我可以看到它收到了它,并在退出之前很好地清理了自己。
问题:
我希望能够将脚本作为SystemD服务运行,因此我创建了一个简单的SystemD服务文件。现在,C#不再正常退出,而是像发送SIGKILL
而不是发送SIGINT
一样立即终止。
这是我当前用于解决此问题的简单测试代码:
import os
import signal
import time
import subprocess
call = ['mono', '/home/user/test.exe'] # (not the actual name of the program, changed for this post)
print('starting')
process = subprocess.Popen(call)
time.sleep(20)
print('sending term')
process.send_signal(signal.SIGINT)
print('term sent')
这是我的SystemD服务文件(将我的实际用户名更改为“用户”):
[Unit]
Description=Test
After=multi-user.target
[Service]
User=user
Group=user
WorkingDirectory=/home/user/testcode
Type=simple
ExecStart=/home/user/testcode/.venv/bin/python /home/user/testcode/test.py
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=testcode
[Install]
WantedBy=multi-user.target
我尝试观察HTOP,以了解Mono进程的PID和GID是否发生任何奇怪的事情,但是在直接启动和SystemD启动的Python脚本之间看起来或多或少都是相同的。>
不幸的是,Mono程序对我来说有点像个黑匣子,所以我对其中发生的事情知之甚少。我确实可以访问源代码,但是我没有C#的经验,也不知道从哪里开始寻找线索。我能够判断它是否正常退出,因为它会生成一个我可以tail
的日志文件,并在正常退出时打印出几行。强制终止时,这些行不会被打印。
我尝试过的事情
我主要尝试了使用Popen.
shell=True
会使C#程序在正常启动时根本不会停止,但是在通过SystemD启动时,它表现出与没有shell=True
时相同的非优雅退出行为。preexec_fn=os.setsid
和os.killpg(os.getpgid(pro.pid), signal.SIGTERM)
,有无shell=True
时没有运气。正常启动和SystemD启动都显示非正常退出。time.sleep(5)
,以使C#有时间在脚本退出之前退出。没变化。我的想法是SystemD看到Python脚本退出,并清理了它产生的所有其他进程,然后才有机会正常退出。