Запуск и остановка подпроцесса snmpd с глобальной переменной
Я запускаю snmpd с подпроцессом, сохраняю ссылку на него как глобальную переменную, затем хочу завершить этот процесс позже.
Я начинаю процесс так:
snmp_proc = subprocess.Popen(['snmpd', '-p', pid_file,'-Lf', log_file],
stdout=open(os.devnull,'w'),stderr=subprocess.STDOUT)
Это начинается правильно, но, кажется, также создает какой-то процесс зомби? выход ps ax дает:
1716 ? Z 0:00 [snmpd] <defunct>
1718 ? S 0:00 snmpd -p /var/run/snmpd.pid -Lf /var/log/snmpd
Теперь, когда я пытаюсь убить процесс позже, уничтожается только несуществующий процесс зомби, а другой процесс остается. Есть идеи, что я делаю не так? Вот код для остановки snmpd:
def stop_snmp():
global snmp_proc
if not snmp_proc:
return
snmp_proc.terminate()
snmp_proc.wait()
snmp_proc = None
1 ответ
<defunct>
означает, что дочерний процесс мертв, но вы не прочитали его состояние выхода (используя snmp_proc.wait()
).
Моя догадка: snmpd
запускает демон ( двойной форк и т. д.) и немедленно возвращается, т. е. чтобы избежать зомби, используйте subprocess.check_call()
вместо subprocess.Popen()
Вот.
Чтобы остановить запущенную службу демона, должна быть специальная команда. Если его нет, тогда читайте pid из pid_file
и использовать его для отправки сигнала (os.kill()
) демону, чтобы убить его.
Я просто решил это, передав -f, чтобы отключить разветвление
Да, отключение демонизирующего поведения - это еще один вариант. snmpd
запускает службу в том же процессе (запущен Popen()
) в этом случае и, следовательно, он не должен становиться зомби, если нет фатальной ошибки, например, если он не запустился.