在python多处理中如何避免父进程等待子进程?

2024-09-27 02:26:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我对python多处理相当陌生,我正在尝试编写一个能够异步执行函数和附加回调的类。你知道吗

首先,让我们为这个特定问题解决一个通用术语:

┬─ process1 (parent)
└─┬─ process2 (child of parent1)
  └─── process3 (child of parent2)

在记录了一些关于这个主题的内容之后,为了做到这一点,我为run方法编写了以下代码:

import multiprocessing


class AsyncProcess:
    def __init__(self, target, callback=None, args=(), kwargs={}):
        self._target = target
        self._callback = callback
        self._args = args
        self._kwargs = kwargs
        self._process = None

    def run(self):
        def wrapper():
            return_value = self._target(*self._args, **self._kwargs)

            if self._callback is not None:
                process = multiprocessing.Process(target=self._callback, args=(return_value,))
                process.start()
                multiprocessing.process._children.discard(process)

        self._process = multiprocessing.Process(target=wrapper)
        self._process.start()

AsyncProcess类比这个大(它是作为multiprocessing.Processsubprocess.Popen之间的适配器,用于在新进程中执行外部进程和python函数);这就是为什么它不是multiprocessing.Process的子类,而只是使用它(以防有人怀疑)。你知道吗

我在这里试图实现的是能够从另一个进程(process2)中启动子进程(process3),而不必(process2)等待子进程(process3)(因为子进程完成的时间可能比父进程长)。multiprocessing.Processdaemon属性没有用,因为当父进程死亡(process2)时,子进程(process3)也被杀死(我只想让它一直运行,直到它完成)。你知道吗

然而,对于我提出的解决方案,有两件事我一点都不喜欢:

  1. 我正在修补multiprocessing的内部结构,我一点也不喜欢。你知道吗
  2. 因为我正在从父进程(process2)的子进程池中删除子进程(process3),所以我猜这会使可怜的子进程成为孤儿(我不知道这到底意味着什么,但最肯定的是这根本不是一个好的实践)。你知道吗

这里的问题是我怎样才能实现父母不等待孩子,而不真正杀死孩子,也不陷入孤儿的过程中?有没有其他更正确或更优雅的方法来实现我的目标?你知道吗

我在考虑将子进程(process3)分配给产生这个子进程(process1)的进程的父进程,也就是子进程的祖辈(我知道它肯定是活的),但是我还没有找到一种方法来真正做到这一点。你知道吗


一些澄清:

  1. Popen实现了我想要实现的功能,但它只对外部进程起作用,也就是说,我不能通过使用Popen(当然,我知道)对所有上下文执行python函数。你知道吗
  2. 我想到了使用os.fork,但是我发现区分父代码和子代码的方法有点麻烦(处理PID == 0PID != 0案例等)。你知道吗
  3. 我没有考虑过任何使用threading包的解决方案,因为我想管理进程,而不是线程,并将线程管理留给操作系统。你知道吗
  4. process1启动process3直接解决了孤立进程的问题,但是接下来我必须在process1上进行主动轮询,以便知道process2何时完成,这实际上不是一个选项(process1管理一个无法阻止的服务器)。你知道吗
  5. 我需要process2尽快完成,以便从中获取一些数据;这就是为什么我不直接在process2内执行process3的内容。你知道吗

我在写问题时想到的东西:

由于我的问题是必须从process2内启动process3并从process1启动它,因此解决了这个问题,但是在process1上进行主动轮询不是一个选项,我也可以同时从process2内启动process2process3,将process2对象传递给process3,并用一个小的命令在process3上执行主动轮询间隔以确保在process2完成后快速响应。你知道吗

对于已经解决的问题(我不知道)来说,这有什么意义或者是一个过于复杂的解决方案?你知道吗


Tags: 方法函数代码selftarget进程callbackargs

热门问题