Процесс, запущенный Celery, не останавливается, когда основной процесс завершается - PullRequest
1 голос
/ 26 сентября 2019

У меня есть работник из сельдерея, который порождает новый процесс для каждой входящей задачи.

@app.task
def add(a, b):
    p = subprocess.Popen(args=['add', a, b], stdout=PIPE, stderr=PIPE)
    stdout, stderr = p.communicate()

Когда процесс сельдерея завершается SIGKILL или холодным выключением, запущенный им процесс Python продолжает выполняться.Даже в иерархии процессов macOS говорит, что родительский процесс больше не существует.Разве дочерний процесс не должен быть также уничтожен, когда родительский процесс неожиданно завершается?

enter image description here

1 Ответ

1 голос
/ 26 сентября 2019

Простой ответ - нет, дочерний процесс не будет автоматически уничтожен, если вы уничтожите родительский процесс.

Этот вопрос github более детально рассмотрен , но tldr заключается в том, что Celery разработан так, чтобы не убивать дочерний процесс случайно, если родительский процесс убит в случае, если дочерний процесс должен завершитьсяпосле того, как родитель уже был казнен.Например, задача, которая указывает другим задачам обновить различные базы данных.После того, как родительский вызов вызван, вы можете открыть родительский рабочий, но вы не обязательно хотите, чтобы дочерние процессы были остановлены, если вы остановите родительский рабочий.

Я использую эту функцию для непосредственного уничтожения дочерних процессов:

from psutil import Process

def terminate_process(pid):

  process = Process(pid)
  for child in process.children(recursive=True):
    child.kill()
  process.kill()

Который вы можете вызвать, чтобы напрямую убить дочерние процессы из PID следующим образом.

celery_process_pid = celery_process.pid
terminate_process(celery_process_pid )
...