使用parallel.futures.ProcessPoolExecutor,我试图运行第一段代码以并行执行功能“ Calculate_Forex_Data_Derivatives(data,gride_spacing)”。当调用结果executor_list [i] .result()时,我得到“ BrokenProcessPool:在将来运行或挂起时,进程池中的进程突然终止。”我尝试运行将函数的多个调用发送到处理池的代码,以及只运行一个将处理函数发送到处理池的代码,这都会导致错误。
我还用一个简单的代码段(提供了第二个代码)测试了代码的结构,该代码具有相同的调用函数输入类型,并且运行良好。我可以在两段代码之间看到的唯一不同是,第一个代码从“ findiff”模块调用了函数“ FinDiff(axis,grid_spacing,derivative_order)”。该功能与“ Calculate_Forex_Data_Derivatives(data,gride_spacing)”一起正常运行时完全可以正常工作。
我正在使用Anaconda环境,Spyder编辑器和Windows。
任何帮助将不胜感激。
#code that returns "BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending."
import pandas as pd
import numpy as np
from findiff import FinDiff
import multiprocessing
import concurrent.futures
def Calculate_Forex_Data_Derivatives(forex_data,dt): #function to run in parallel
try:
dClose_dt = FinDiff(0,dt,1)(forex_data)[-1]
except IndexError:
dClose_dt = np.nan
try:
d2Close_dt2 = FinDiff(0,dt,2)(forex_data)[-1]
except IndexError:
d2Close_dt2 = np.nan
try:
d3Close_dt3 = FinDiff(0,dt,3)(forex_data)[-1]
except IndexError:
d3Close_dt3 = np.nan
return dClose_dt, d2Close_dt2, d3Close_dt3
#input for function
#forex_data is pandas dataframe, forex_data['Close'].values is numpy array
#dt is numpy array
#input_1 and input_2 are each a list of numpy arrays
input_1 = []
input_2 = []
for forex_data_index,data_point in enumerate(forex_data['Close'].values[:1]):
input_1.append(forex_data['Close'].values[:forex_data_index+1])
input_2.append(dt[:forex_data_index+1])
def multi_processing():
executors_list = []
with concurrent.futures.ProcessPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
for index in range(len(input_1)):
executors_list.append(executor.submit(Calculate_Forex_Data_Derivatives,input_1[index],input_2[index]))
return executors_list
if __name__ == '__main__':
print('calculating derivatives')
executors_list = multi_processing()
for output in executors_list
print(output.result()) #returns "BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending."
##############################################################
#simple example that runs fine
def function(x,y): #function to run in parallel
try:
asdf
except NameError:
a = (x*y)[0]
b = (x+y)[0]
return a,b
x=[np.array([0,1,2]),np.array([3,4,5])] #function inputs, list of numpy arrays
y=[np.array([6,7,8]),np.array([9,10,11])]
def multi_processing():
executors_list = []
with concurrent.futures.ProcessPoolExecutor(max_workers=multiprocessing.cpu_count()) as executor:
for index,_ in enumerate(x):
executors_list.append(executor.submit(function,x[index],y[index]))
return executors_list
if __name__ == '__main__':
executors_list = multi_processing()
for output in executors_list: #prints as expected
print(output.result()) #(0, 6)
#(27, 12)
答案 0 :(得分:0)
我知道三种打破ProcessPoolExecutor管道的典型方法:
您的系统遇到限制,很可能是内存不足,并开始终止进程。由于Windows上的fork会克隆您的内存内容,因此在使用大型DataFrame时这并非不可能。
子流程的Python实例由于未引发适当Exception的错误而终止。一个示例是导入的C模块中的段错误。
由于您的代码在没有PPE的情况下可以正常运行,所以我唯一想到的情况是某些模块不是多处理安全的。然后它也有机会与max_workers=1
一起消失。通过在创建工作进程之后立即手动调用函数(在调用max_workers=1
的for循环之后的行),也有可能在主进程中引发错误。
否则,可能很难确定,但我认为这是最不可能的情况。
管道的子进程侧(即处理通信的代码)可能会崩溃,从而导致适当的异常,不幸的是,该异常无法传达给主进程。
由于(希望)对代码进行了良好的测试,所以主要的可疑之处在于返回数据。必须将其腌制并通过套接字发送回去-这两个步骤都可能崩溃。因此,您必须检查:
因此,您可以尝试返回一些简单的伪数据,或者显式检查两个条件:
executor.submit
在Python 3.7中,此问题已修复,并且将异常发回。
答案 1 :(得分:0)
我在官方文档中找到了这个:
<块引用>“main 模块必须可由工作子进程导入。这意味着 ProcessPoolExecutor 将无法在交互式解释器中工作。从提交给 ProcessPoolExecutor 的可调用对象调用 Executor 或 Future 方法将导致死锁。 "
你有没有试过这个?以下对我有用:
if __name__ == '__main__':
executors_list = multi_processing()
for output in executors_list:
print(output.result())