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



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

首先,让我们为这个特定问题解决一个通用的命名法:

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

在对我进行了一些关于这个主题的记录,并遵循这个SO问题之后,为了做到这一点,我为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(,而不必等待子进程(process2process3((因为子进程可能需要比父进程更长的时间(。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进行主动轮询不是一种选择,所以我也可以同时从process1内部启动process2process3,将process2对象传递给process3并以较小的间隔对process3执行主动轮询,以确保CC_后的快速响应43 完成。

这是否有任何意义,或者对于已经解决(我不知道(的事情来说,这是一个过于复杂的解决方案?

如果没有您想要避免的内部结构的修补,就不可能使用多处理库来执行您想要做的事情(忽略它是否是一个好主意的问题(,正是因为多处理库是专门为不会比父进程寿命更长的子进程设计的。

我认为答案确实是使用subprocess.Popen(),尽管这意味着放弃多处理库的漂亮高级 API。不可以,您不能直接执行 Python 函数,但您可以创建一个单独的 script.py 来调用所需的函数。

相关内容

  • 没有找到相关文章