Python 使用多处理在类方法的while循环中运行函数

Python 使用多处理在类方法的while循环中运行函数,python,parallel-processing,multiprocessing,Python,Parallel Processing,Multiprocessing,我有一种方法,可以使用多种其他方法计算最终结果。它有一个while循环,其中不断检查新数据,如果收到新数据,它将运行其他方法并计算结果。这个main方法是用户唯一调用的方法,在程序关闭之前它一直处于活动状态。基本结构如下: class sample: def __init__(self): results = [] def main_calculation(self): while True: #c

我有一种方法,可以使用多种其他方法计算最终结果。它有一个while循环,其中不断检查新数据,如果收到新数据,它将运行其他方法并计算结果。这个main方法是用户唯一调用的方法,在程序关闭之前它一直处于活动状态。基本结构如下:

class sample:
     def __init__(self):
           results = []
     def main_calculation(self):
           while True:
                 #code to get data
                 if newdata != olddata:
                       #insert code to prepare data for analysis
                       res1 = self.calc1(prepped_data)
                       res2 = self.calc2(prepped_data)
                       final = res1 + res2
                       self.results.append(final)
我想并行运行calc1和calc2,以便更快地获得最终结果。但是,我不确定如何以这种方式实现多处理,因为我没有使用
\uuuu main\uuu
保护。有没有办法并行运行这些进程

对于这段代码来说,这可能不是最好的组织,但对于我正在运行的实际计算来说,这是最容易的,因为有必要从不同的文件导入并运行这段代码。但是,如果这不是一个可挽救的结构,我可以重新构造代码。

根据,您需要使用
\uuuuu main\uuuuu
保护的原因是,当您的程序创建
多处理.Process
对象时,它会启动Python解释器的一个全新副本,该副本将导入程序模块的一个新副本。如果导入模块调用
multiprocessing.Process()
本身,则将创建Python解释器的另一个副本,该解释器将解释代码的另一个副本,依此类推,直到系统崩溃(或者实际上,直到Python命中一段不可重入的多处理代码)

在程序的主模块(通常在顶层调用一些代码)中,检查
\uuuuuu name\uuuuu='\uuuuu main\uuuu'
可以判断程序是第一次运行还是作为子进程运行。但是在另一个模块中,顶层可能没有任何代码(定义除外),在这种情况下,不需要使用防护,因为可以安全地导入模块而无需启动新进程

换句话说,这是危险的:

将多处理导入为mp
def():
...
p=mp.过程(目标=f)
p、 开始()
p、 加入
但这是安全的:

将多处理导入为mp
def():
...
def g():
p=mp.过程(目标=f)
p、 开始()
p、 加入
这也是安全的:

将多处理导入为mp
def():
...
H类:
def g(自我):
p=mp.过程(目标=f)
p、 开始()
p、 加入
因此,在您的示例中,您应该能够在函数中直接创建
Process
对象

但是,我建议在类的文档中明确说明,该方法创建了一个
过程
,因为无论谁使用它(可能是您)都需要知道,在模块的顶层调用该方法是不安全的。这就像这样,也属于“危险”类别:

将多处理导入为mp
def():
...
H类:
def g(自我):
p=mp.过程(目标=f)
p、 开始()
p、 加入
H().g()#这将在顶层创建一个流程
<>你也可以考虑另一种方法,让调用方完成所有的进程创建。在这种方法中,您的
sample
类构造函数或
main_calculation()
方法都可以接受(比如)一个
Pool
对象,并且它可以使用该池中的进程来进行计算。例如:

类示例:
def主_计算(自身、池):
尽管如此:
如果是新数据!=旧数据:
res1\u async=pool.apply\u async(self.calc1,[prepped\u data])
res2\u async=pool.apply\u async(self.calc2,[prepped\u data])
res1=res1\u async.get()
res2=res2_async.get()
#等等

如果有许多不同的计算发生,这种模式还可以使您的程序在使用资源方面更加高效,因为它们都可以使用相同的进程池。

您能否澄清一下
\uuuuu main\uuuu
guard与多处理有什么关系?我不太确定我是否理解你真正想知道的,但我希望有了这个问题的答案会让事情变得更清楚。@DavidZ你好!到目前为止,在我找到的所有示例中,用于启动并行进程的行都位于主保护内部,并且我发现了一个错误的引用,该错误在不使用时出现:当我尝试从while循环内部并行启动进程时,我也遇到了这个错误。非常感谢。好的,谢谢,这确实有助于澄清问题。你能编辑你的问题,让它包含这些信息吗?我看看能不能想出一个答案。