带有内部方法的流程实例化

Process instanciation w/ its internal methods

我对 Python 多进程编程有点不知所措。之前来这里问,看了那么多,还是没找到问题的答案

问题是这个:我正在尝试在 rpi3 上创建一个软件以集中一组探针 (rs232 and/or i²c)。这些可能同时使用,因此该应用程序必须具有低延迟的灵活性(对于某些气体,频率必须为 /ms 甚至 /µs)。

我习惯了 C(所以很快就选择了 multi-thread/multi-process),但对 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 class 的私有方法不能再使用了..!? 我没有找到关于该主题的任何内容..只有 "processes starting methods" 或 "classes w/out private methods".

我的实际代码:

https://github.com/OkTekk/a.gus/blob/master/log_manager.py https://github.com/OkTekk/a.gus/blob/master/licor_6xx.py

在 C 术语中,Process 对象只是通往另一个进程的桥梁:它实现 fork 并在新进程中调用一个函数。但是,在您调用其 start 方法之前,它实际上不会创建其他进程。所以通常的模式是:

p = Process(target=SomeFunction, args=(whatever...), kwargs={...})
p.start()

现在,SomeFunction 需要是一个 "callable" 并且它需要在子进程中完成您想完成的任何事情。您将 Licor6xx 作为可调用对象。因为它是一个 class 名称,所以它 可调用的。调用它将创建对象,并调用其 __init__ 方法。但是,没有任何东西可以维护对象的生命周期并为您操作它。 (也就是说,if/when__init__方法returns,Processtarget方法已经完成,所以子进程会直接退出。)

所以一种可能的方法是:

# 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()。那将是您添加到对象的方法。它可以通过调用对象的其他方法来做任何它想做的事情。在您准备好退出进程之前,您不希望它 return。

请注意,这实际上是在父对象中创建对象,子对象将拥有它,因为fork复制了整个地址[=62] =]. (父级中的副本将自动销毁 if/when 你删除引用 - 即当 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.probeProcess 对象,而不是您的 Licor6xx 对象。 Process 对象没有 connect 方法。但更重要的是,由于您打算将探测器放在它自己的进程中:您不能在进程 A 中的对象上调用方法并影响进程 B 中的对象的状态。fork 之后,两个进程完全不同的地址 spaces.

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