我对Python多进程编程有点不知所措。以前,来这里问一下,我已经阅读了很多内容,但仍未找到答案。
问题出在这一点:我正在尝试在rpi3上创建一个软件来集中一组探针(rs232和/或i²c)。那些可能同时使用,因此该应用必须具有低延迟的灵活性(对于某些气体,频率必须是/ ms或甚至/μs)。
我已经习惯了C(因此很快就选择了多线程/多进程),但对OO语言来说却是新手。
我实际上尝试为每个传感器创建一个独特的过程,以便能够执行实时控制,配置,绘图等。
if (self.device == 6262):
self.probe = Process(target=Licor6xx,
args=((self.q_in, self.q_out), self.q_header),
kwargs=self.kwargs)
self.probe.connect() # here it comes, the 'do not work anymore'.
但是,然后,Licor6xx类的私有方法不能再使用..!? 我还没有找到关于该主题的任何内容......只是“处理启动方法”或“类没有私有方法”。
我的实际代码:
https://github.com/OkTekk/a.gus/blob/master/log_manager.py https://github.com/OkTekk/a.gus/blob/master/licor_6xx.py
答案 0 :(得分:0)
在C语言中,Process
对象只是进入另一个进程的桥梁:它实现fork
并在新进程中调用一个函数。但是,在调用其start
方法之前,它实际上不会创建其他进程。通常的模式是:
p = Process(target=SomeFunction, args=(whatever...), kwargs={...})
p.start()
现在,SomeFunction
需要是“可调用的”,并且它需要在子进程中执行您想要完成的任何操作。您将Licor6xx
作为可调用对象。由于它是类名,因此是可调用的。调用它将创建对象,并调用其__init__
方法。但是,没有什么能够维持对象的生命周期并为您操作它。 (也就是说,如果/ __init__
方法返回时,Process
的{{1}}方法已完成,因此子进程将退出。)
所以一种可行的方法是:
target
在fork之后,进程对象将调用# Create the probe object.
lobj = Licor6xx()
# Create a subprocess, giving it a bound method in the probe object
self.probe = Process(target=lobj.run, args=....)
# Fork and start the child process
self.probe.start()
。这将是您添加到对象的方法。它可以通过调用对象的其他方法来做任何事情。在您准备好退出流程之前,您不希望它返回。
请注意,这实际上是在父对象中创建对象,由于lobj.run()
复制了整个地址空间,子对象也。 (如果/当你删除引用时,父进程中的副本将被自动销毁 - 即当fork
超出范围时。)因此,如果你不想或不需要在父进程中创建对象,那么另一个这样做的方法是提供一个独立的函数lobj
并让它创建你的探测对象:
target
另一件事:在您提供的代码中,您尝试调用def run([args]):
lobj = Licor6xx()
while True:
# Do stuff with lobj
lobj.foo()
self.probe = Process(target=run, args=(...))
self.probe.start()
,但self.probe.connect()
是self.probe
对象,而不是您的Process
对象。 Licor6xx
对象没有Process
方法。但更重要的是,因为您打算将探针放在自己的进程中:您不能在进程A中调用对象上的方法并影响进程B中对象的状态。在fork之后,这两个进程完全没有不同的地址空间。
如果您想与子进程通信,您应该使用connect
或Pipe
对象或父母和孩子都能看到的其他IPC机制(显然需要设置) 之前在Queue
对象上调用start
。通常,您将IPC对象引用(或文件句柄或其他)作为Process
参数之一提供。