我有一种方法可以使用多种其他方法来计算最终结果。它具有一个while循环,该循环中不断检查新数据,如果接收到新数据,它将运行其他方法并计算结果。该主要方法是用户调用的唯一方法,并且在关闭程序之前一直保持活动状态。基本结构如下:
@Component({
selector: "app-foo",
templateUrl: "./foo.component.html",
styleUrls: ["./foo.component.scss"]
})
export class FooComponent extends BaseComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.store.dispatch(ApplicationFooItemsRequestedAction());
this.fooList$ = this.store.select(selectAllApplicationFooItems);
this.fooList$.pipe(takeUntil(untilDestroyed(this))).subscribe(ul => {
// do stuff with items
});
}
}
我想并行运行calc1和calc2,以便可以更快地获得最终结果。但是,由于我没有使用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)
保护,因此我不确定如何以这种方式实现多重处理。有什么办法可以并行运行这些进程?
这可能不是此代码的最佳组织,但是对于我正在运行的实际计算而言,这是最简单的方法,因为有必要将此代码导入并从其他文件运行。但是,如果这不是一种可挽救的结构,我可以重组代码。
答案 0 :(得分:1)
根据the documentation,您需要使用__main__
保护的原因是,当程序创建multiprocessing.Process
对象时,它将启动Python解释器的全新副本,将导入程序模块的新副本。如果导入模块本身调用multiprocessing.Process()
,则将创建Python解释器的另一个副本,该副本解释代码的另一个副本,依此类推,直到系统崩溃(或实际上,直到Python遇到不可重入的片段为止)多处理代码)。
在程序的主模块(通常会在顶层调用某些代码)中,检查__name__ == '__main__'
是您判断程序是首次运行还是作为子进程运行的方式。但是在不同的模块中,顶层可能没有任何代码(定义除外),在这种情况下,无需使用防护,因为可以安全地导入模块而无需启动新进程。
换句话说,这很危险:
import multiprocessing as mp
def f():
...
p = mp.Process(target=f)
p.start()
p.join()
但这很安全:
import multiprocessing as mp
def f():
...
def g():
p = mp.Process(target=f)
p.start()
p.join()
这也是安全的:
import multiprocessing as mp
def f():
...
class H:
def g(self):
p = mp.Process(target=f)
p.start()
p.join()
因此在您的示例中,您应该能够直接在函数中创建Process
对象。
但是,我建议在类的文档中明确指出该方法创建了Process
,因为无论使用它的人(也许您)都需要知道在该方法处调用该方法并不安全。模块的顶层。就像这样做,它也属于“危险”类别:
import multiprocessing as mp
def f():
...
class H:
def g(self):
p = mp.Process(target=f)
p.start()
p.join()
H().g() # this creates a Process at the top level
您还可以考虑使用另一种方法,使调用者完成所有流程的创建。在这种方法中,您的sample
类构造函数或main_calculation()
方法都可以接受一个Pool
对象,并且可以使用该池中的进程进行计算。例如:
class sample:
def main_calculation(self, pool):
while True:
if newdata != olddata:
res1_async = pool.apply_async(self.calc1, [prepped_data])
res2_async = pool.apply_async(self.calc2, [prepped_data])
res1 = res1_async.get()
res2 = res2_async.get()
# and so on
如果发生许多不同的计算,此模式还可以使您的程序更有效地利用资源,因为它们都可以使用相同的进程池。