首页 > 解决方案 > 当主进程终止时,由 Celery 启动的进程不会停止

问题描述

我有一个 celery worker 为每个传入任务生成一个新进程。

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

当 celery 进程被 SIGKILL 或冷关机终止时,它启动的 Python 进程继续运行。即使在进程层次结构中,macOS 确实说父进程不再存在。当父进程意外终止时,子进程不应该被杀死吗?

在此处输入图像描述

标签: pythonmacoscelerycelery-task

解决方案


简单的答案是否定的,如果您杀死父进程,子进程不会自动被杀死。

这个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 )

推荐阅读