【问题标题】:Cleanup child processes in multiprocessing在多处理中清理子进程
【发布时间】:2020-02-27 06:45:41
【问题描述】:

考虑一个子进程的简单设置。基本上是生产者(父)-消费者(子)的场景。

class Job:
    def start_process(self):
        self.queue = multiprocessing.Queue(3)
        self.process = multiprocessing.Process(target=run,
                                               args=(self.queue))

def run(queue):
    while True:
        item = queue.get()
        ....

如果我在父进程上执行kill -9,子进程将永远挂起。我确信它会像subprocess.Popen 一样收到SIGHUP - 当python 进程退出时,popened 也会退出。知道如何解决子清理问题吗?

【问题讨论】:

  • 如果您在调用 multiprocessing.Process() 时提供了 daemon=True 参数,则子进程将在主进程结束时自动被杀死(假设您使用的是 Python 3.3+)。
  • 必须使用 pypy 并使用 2.7 ((.
  • 不知道 pypi 是如何影响事物的,但是对于早期版本的 Python,您可以在调用 start() 方法之前使用 self.process.daemon = True 手动设置属性。
  • @martineau 不起作用 - 孤儿仍在挂起。
  • @martineau 这不是 PyPI 它是 PyPy,我已经谈过了,是的,它与问题无关。

标签: python python-2.7 multiprocessing python-multiprocessing


【解决方案1】:

如果daemon 参数对您不起作用,您可以捕获一个 SIGINT 信号并让它设置一个布尔值以退出您孩子的 while 循环。即..

import signal

g_run_loops = True
def signal_handler(signum, frame):
   global g_run_loops
   g_run_loops = False

signal.signal(signal.SIGINT, signal_handler)

def run(queue):
    global g_run_loops
    while g_run_loops:
        item = queue.get()
        ....

请注意,这不适用于 SIGKILL (kill -9),但应该适用于 SIGINT (kill -2)。

【讨论】:

  • 我认为kill -9期间没有任何SIGINT
  • 同意。无法捕获 SIGKILL,但您可以发出 SIGINT(ctrl-c 或 kill -2)吗?
  • 我正在寻找一些通用解决方案来处理 python 崩溃,它是儿童。 kill -9 只是一个可重现的例子。
  • 如果daemon 参数和信号处理不起作用,我认为您唯一的选择是使用ps 命令找到它们并单独杀死它们。如果它经常发生,bash 脚本可以简化它。 psutil 库也有一些很好的函数来查找进程。
猜你喜欢
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多