gpt4 book ai didi

python - multiprocessing 产生已失效的进程

转载 作者:太空狗 更新时间:2023-10-30 02:26:18 25 4
gpt4 key购买 nike

我使用Tornado作为web服务器,用户可以通过前端页面提交任务,审核通过后就可以启动提交的任务了。在这种情况下,我想启动一个异步子进程来处理任务,所以我在请求处理程序中编写了以下代码:

def task_handler():
// handle task here

def start_a_process_for_task():
p = multiprocessing.Process(target=task_handler,args=())
p.start()
return 0

我不关心子流程,只为它启动一个流程,然后返回到前端页面,告诉用户任务已启动。任务本身将在后台运行,并将其状态或结果记录到数据库中,以便用户稍后可以在网页上查看。所以在这里我不想使用阻塞的 p.join() ,但是在任务完成后没有 p.join() ,子进程变成一个不存在的进程,并且当 Tornado 作为守护进程运行并且永远不会退出时,不存在的进程永远不会消失。

谁知道如何解决这个问题,谢谢。

最佳答案

避免失效子级的正确方法是让父级优雅地清理并关闭已退出子级的所有资源。这通常由 join() 完成,但如果您想避免这种情况,另一种方法可能是为父级上的 SIGCHLD 信号设置一个全局处理程序。

SIGCHLD 将在子进程退出时发出,如果您仍然可以访问进程对象,则在处理函数中您应该调用 Process.join(),甚至使用 os.wait() 来“等待”任何子进程终止并正确地获取它。此处的等待时间应该为 0,因为您肯定知道子进程刚刚退出。您还可以获得进程的退出代码/终止信号,因此它也是处理/记录子进程崩溃的有用方法。

这是一个简单的例子:

from __future__ import print_function

import os
import signal
import time
from multiprocessing import Process


def child_exited(sig, frame):
pid, exitcode = os.wait()
print("Child process {pid} exited with code {exitcode}".format(
pid=pid, exitcode=exitcode
))


def worker():
time.sleep(5)
print("Process {pid} has completed it's work".format(pid=os.getpid()))


def parent():
children = []

# Comment out the following line to see zombie children
signal.signal(signal.SIGCHLD, child_exited)

for i in range(5):
c = Process(target=worker)
c.start()
print("Parent forked out worker process {pid}".format(pid=c.pid))
children.append(c)
time.sleep(1)

print("Forked out {c} workers, hit Ctrl+C to end...".format(c=len(children)))
while True:
time.sleep(5)


if __name__ == '__main__':
parent()

需要注意的是,我不确定此过程是否适用于非 Unix 操作系统。它应该可以在 Linux、Mac 和其他 Unix 上运行。

关于python - multiprocessing 产生已失效的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45505981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com