Отправка SIGINT в подпроцесс не работает, когда скрипт Python работает как служба sytemd - PullRequest
0 голосов
/ 03 февраля 2020

Справочная информация:

У меня есть C# программа, которую я запускаю под Mono на Linux (в частности, Raspbian). Я работаю над Python скриптом, который запускает эту программу, контролирует ее и грациозно убивает. Я использую subprocess.Popen для запуска программы 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 (изменил мое действительное имя пользователя на 'user'):

[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, чтобы увидеть, происходит ли что-то странное с что такое PID и GID для процессов Mono, но все выглядит более-менее одинаково между прямым запуском и запущенным сценарием 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 и очищает все остальные процессы, которые он вызвал, прежде чем они получат шанс завершить работу корректно.
...