我对Python的多进程编程还比较陌生,我正在尝试编写一个类,能够异步执行函数并附加回调函数。
首先,让我们为这个特定问题解决一个常见的命名问题:
在帮我了解一下这个主题后,我按照这个SO问题的建议,编写了如下代码以实现目标:
首先,让我们为这个特定问题解决一个常见的命名问题:
┬─ 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.Process
和 subprocess.Popen
之间的适配器,用于在新进程中执行外部进程和 Python 函数);这就是为什么它不是 multiprocessing.Process
的子类,而只是在使用它(如果有人想知道的话)。
我想要实现的目标是能够从另一个进程(process2
)中启动一个子进程(process3
),而不必等待它(process2
)(因为子进程可能需要比父进程更长的时间才能完成)。multiprocessing.Process
的 daemon
属性并没有用,因为当父进程(process2
)死亡时,子进程(process3
)也会被杀死(而我只想让它一直运行直到完成)。
然而,有两件事情我都不喜欢:
- 我正在玩弄
multiprocessing
的内部结构,这一点我一点也不喜欢。 - 由于我将子进程(
process3
)从父进程(process2
)的子进程池中删除,我猜这会让可怜的孩子成为孤儿(我不知道确切的含义,但肯定不是好的做法)。
问题在于如何实现父进程不等待子进程而又不杀死子进程或陷入孤儿进程?有没有其他更正确或更优雅的方法来实现我想要做的事情?
我正在考虑将子进程(process3
)分配给产生该子进程的进程的父进程(process1
),即子进程的曾祖父进程(我知道它肯定还活着),但我还没有找到实现这一点的方法。
一些澄清:
Popen
可以实现我想要的目标,但它只能处理外部进程,也就是说我不能使用Popen
来执行带有所有上下文的Python函数(当然,这是我所知道的)。- 使用
os.fork
已经考虑过了,但我觉得区分父进程和子进程的方式有点麻烦(处理PID == 0
和PID != 0
的情况等)。 - 我没有考虑使用
threading
包的任何解决方案,因为我想管理进程而不是线程,并将线程管理留给操作系统。 - 直接从
process1
启动process3
解决了孤立进程的问题,但我必须对process1
进行主动轮询,以便知道process2
何时完成,这实际上不是一个选项(process1
管理一个不能被阻塞的服务器)。 - 我需要尽快让
process2
完成以获取一些数据;这就是为什么我不直接在process2
中执行process3
内容的原因。
在撰写问题时我想到的解决方案:
由于我的问题是必须从process2
内部启动process3
,而从process1
启动可以解决问题,但在process1
上进行主动轮询不可行,因此我也可以同时从process1
内部启动process2
和process3
,将process2
对象传递给process3
,并使用小间隔对process3
进行主动轮询,以确保在process2
完成后快速响应。
这个方法是否有意义,或者是对已经解决的问题进行了过度复杂的解决方案(而我不知道)?
process1
除了生成新进程之外无法执行任何其他操作,process2
需要尽早结束(因为我需要进程的退出代码尽快可用于其他目的),而process3
则用于执行process2
的适当回调函数。也许我对这个问题的整体思考方式不正确;我会查看您的建议,看看它们是否符合我的目的。 - Alejandro de Haro