[英]Python multiprocessing code runs fine, but does not terminate
我有这个代码(我很抱歉它几乎是我工作代码的精确复制粘贴。我不知道问题可能在哪里,因此我把它全部放在这里):
def init(Q):
"""Serves to initialize the queue across all child processes"""
global q
q = Q
def queue_manager(q):
"""Listens on the queue, and writes pushed data to file"""
while True:
data = q.get()
if data is None:
break
key, preds = data
with pd.HDFStore(hdf_out, mode='a', complevel=5, complib='blosc') as out_store:
out_store.append(key, preds)
def writer(message):
"""Pushes messages to queue"""
q.put(message)
def reader(key):
"""Reads data from store, selects required days, processes it"""
try:
# Read the data
with pd.HDFStore(hdf_in, mode='r') as in_store:
df = in_store[key]
except KeyError as ke:
# Almost guaranteed to not happen
return (key, pd.DataFrame())
else:
# Executes only if exception is not raised
fit_df = df[(df.index >= '2016-09-11') & \
(df.index < '2016-09-25') & \
(df.index.dayofweek < 5)].copy()
pre_df = df[(df.index >= '2016-09-18') & \
(df.index < '2016-10-2') & \
(df.index.dayofweek < 5)].copy()
del df
# model_wrapper below is a custom function in another module.
# It works fine.
models, preds = model_wrapper(fit_df=fit_df, pre_df=pre_df)
if preds is not None:
writer((key, preds))
del preds
return (key, models)
def main():
sensors = pd.read_csv('sens_metadata.csv', index_col=[0])
nprocs = int(cpu_count() - 0)
maxproc = 10
q = Queue()
t = Thread(target=queue_manager, args=(q,))
print("Starting process at\t{}".format(dt.now().time()))
sys.stdout.flush()
t.start()
with Pool(processes=nprocs, maxtasksperchild=maxproc, initializer=init,
initargs=(q,)) as p:
models = p.map(reader, sensors.index.tolist(), 1)
print("Processing done at\t{}".format(dt.now().time()))
print("\nJoining Thread, and finishing writing predictions")
sys.stdout.flush()
q.put(None)
t.join()
print("Thread joined successfully at\t{}".format(dt.now().time()))
print("\nConcatenating models and serializing to pickle")
sys.stdout.flush()
pd.concat(dict(models)).to_pickle(path + 'models.pickle')
print("Pickled successfully at\t{}".format(dt.now().time()))
if __name__ == '__main__':
main()
这段代码表现得像一个严重偏向的抛硬币。 大部分时间它都不起作用,有时它起作用。 当它运行时,我知道完成运行整个数据(所有keys
)大约需要2.5小时。 10个运行中的9个,它将处理所有数据,我看到hdf_out
文件中的数据,但多处理池没有加入。 所有子进程都处于活动状态,但没有做任何工作。 我只是不明白为什么这个程序可能会挂起来。
当发生这种情况时,我没有看到"Processing done at ..."
和"Joining Thread, ..."
消息。 此外,如果我给它更小的数据集,它就完成了。 如果我排除了preds
计算,它就完成了。 我不能排除没有大量修改的models
计算,这将不利于项目的其余部分。
我不知道为什么会这样。 我正在使用Linux(Kubuntu 16.04)。
显然放弃maxtaskperchild
kwag解决了这个问题。 为什么我不清楚地理解。 我想它与fork进程(Linux上的默认值)和spawn进程(Windows上的唯一选项)之间的区别有关。
使用fork进程maxtaskperchild
显然不是必需的,因为如果没有它,性能会更好。 我注意到通过删除maxtaskperchild
改进了内存使用。 内存不会被子进程占用,而是从父进程共享。 但是,当我不得不使用Windows时, maxtaskperchild
是防止子进程膨胀的关键方法,尤其是在运行具有长任务列表的内存密集型任务时。
有人知道发生了什么变化,请随时编辑这个答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.