流程实例与其内部方法

时间:2016-12-21 20:41:36

标签: python-2.7 python-multiprocessing

我对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

1 个答案:

答案 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之后,这两个进程完全没有不同的地址空间。

如果您想与子进程通信,您应该使用connectPipe对象或父母和孩子都能看到的其他IPC机制(显然需要设置) 之前Queue对象上调用start。通常,您将IPC对象引用(或文件句柄或其他)作为Process参数之一提供。