多处理过程在创建时直接开始



嗨,我在python 3.7中遇到多处理问题 我做了一个侦听器,它应该在不阻塞程序其余部分(异步通信)的情况下等待来自服务器的响应:

self = cl.appendSend('bar', base_list)
print("client erstellt neuen nebenläufigen listener, für die Antwort des Servers")
multiprocessing.set_start_method("spawn")
queue = multiprocessing.Queue()
process = multiprocessing.Process(target = cl.appendResponse(), args=(self))
process.start()
print("listener aktiv")
thread = threading.Thread(target= waitingPrinter(), args=(process, queue))
print(thread)

是一切开始的地方 但是生产线process = multiprocessing.Process(target = cl.appendResponse(), args=(self))启动一次,运行一次,然后在完成后,它只是再次运行。调试器永远不会离开此行。

进程中运行的方法为:

def appendResponse(self):
print("nebenläufiger listener aktiv")
msgrcv = self.chan.receive_from(self.server)
print("nebenläufiger listener hat Antwort erhalten")
return msgrcv  # pass it to caller

可悲的是,由于版权的原因,我无法真正发布更多内容,但是该方法第一次运行良好,第二次失败,并显示消息: 回溯(最近一次调用):

> File "D:/Verteile Systeme 2/neues Lab/git/vs2lab/lab2/rpc/runcl.py",
> line 27, in <module>
>     process = multiprocessing.Process(target = cl.appendResponse(), args=(self))   File "C:Program Files
> (x86)Python37-32libmultiprocessingprocess.py", line 82, in
> __init__
>     self._args = tuple(args) TypeError: 'Client' object is not iterable

所以我想知道,为什么cl.appendResponse()的进程甚至在绑定到进程时就开始了,而不是等待process.start(),如果还没有答案,为什么它会直接运行第二次。当然,我该如何解决这个问题。

还有没有办法用线程替换处理并仍然获得返回值? 我在处理和返回值时遇到了很多麻烦。

target = cl.appendResponse()将运行该函数并将结果返回到目标。 正确的语法是target=cl.appendResponse它将告诉进程在start()上运行cl.appendResponse。

菲利普在他们的回答中正确地陈述了该过程明显立即执行的原因。
Processtarget参数采用可调用的对象,即由run()方法调用的对象。您的代码传递self.chan.receive_from(self.server)返回的任何内容。
没有子进程在行process = multiprocessing.Process(target = cl.appendResponse(), args=(self))中运行。您的方法在主进程中运行并阻止它。
附带说明:您将遇到完全相同的问题thread,出于同样的原因:thread = threading.Thread(target= waitingPrinter(), args=(process, queue))

方法在主进程中执行完后,进程对象的初始化将引发BaseProcess类的__init__方法内的TypeError
将参数self传递给进程,但操作不正确。args参数需要一个参数元组。如果仅指定单个值,则通过文本创建元组需要一个尾随逗号:args=(self,).您的代码有效地传递self,即直接传递Client对象,这是不可迭代的,因此会导致错误。
在您的情况下,appendResponse似乎是Client对象的绑定方法。它将通过 Python 类系统的内部工作原理接收self参数。通过流程显式传递它将引发另一个TypeError,即将两个位置参数传递给仅接受一个的方法。除非appendSend返回除调用它的Client实例cl以外的其他内容,否则请在进程实例化中删除args参数。

另一方面注意:启动方法spawn是Windows上唯一可用的方法,因此是默认方法。除非你的代码需要使用该启动方法在 Unix 下运行,否则这一行是多余的:multiprocessing.set_start_method("spawn")

最新更新