Демон в python генерирует несуществующий/зомби-процесс linux

Я пытаюсь создать длинные процессы из фляжного приложения. Итак, у меня есть основной процесс, который обрабатывает входящие веб-запросы и из которого я запускаю демоны, используя библиотеку python-daemon. Вот минимальный рабочий пример:

import os
import time
import daemon
import lockfile

def daemon_function():
    return True

working_directory = os.path.dirname(os.path.abspath(__file__))
pid_file = os.path.join(working_directory,"my_daemon.pid")

daemon_context = daemon.DaemonContext(
        working_directory=working_directory,
        pidfile=lockfile.FileLock(pid_file),
    )

pid = os.fork()
if pid == 0:
    with daemon_context:
        daemon_function()

time.sleep(10)

Когда я использую команду linux ps -ef, пока основной процесс все еще работает, после завершения процесса демона я вижу этот вывод:

user     2484     1  0 09:38 ?        00:00:01 /lib/systemd/systemd --user
user    11269  6061  0 12:07 pts/2    00:00:00 bash
user    28817 11269  1 15:43 pts/2    00:00:00 python test_daemon.py
user    28818 28817  0 15:43 pts/2    00:00:00 [python] <defunct>

Причина, по которой я использую функцию fork перед оператором with daemon_context:, заключается в том, что мне нужно, чтобы основной процесс продолжался.

Должен ли я беспокоиться о созданном несуществующем процессе (я могу создать их много)? Как я мог избежать появления этого зомби?


person Robin    schedule 12.03.2019    source источник


Ответы (1)


Если вы не хотите создавать зомби-процессы, вы должны дождаться их завершения, т.е. выполнить системный вызов ожидания вместо сна:

import os
import time
import daemon
import lockfile

def daemon_function():
    return True

working_directory = os.path.dirname(os.path.abspath(__file__))
pid_file = os.path.join(working_directory,"my_daemon.pid")

daemon_context = daemon.DaemonContext(
        working_directory=working_directory,
        pidfile=lockfile.FileLock(pid_file),
    )

pid = os.fork()
if pid == 0:
    with daemon_context:
        daemon_function()

os.waitpid(pid, 0)
person Dariusz Ostolski    schedule 12.03.2019
comment
Хм, да, это было намного проще, чем я ожидал :-). На самом деле вы можете оставить последнюю строку time.sleep(10) в конце, что представляет собой своего рода бесконечный цикл. Поскольку родительский pid ничего не делает, последний os.waitpid(pid, 0) мгновенно достигается. Спасибо - person Robin; 12.03.2019