我在具有以下基本结构(伪代码)的服务器上运行python脚本:
for data_item in data_items:
processed_result=process_data(data_item); #this takes time T0
upload_result_to_site(processed_result) #this takes time T1
基本约束是:
data_items
是一个(大)数据列表process_data()
使用了很多CPU。upload_result_to_site()
占用的CPU很少。T0
= 5*T1
(大约)现在,我的服务器时间有限,我想将所有时间用于CPU密集型process_data()
,而不是upload_result()
上。不幸
upload_result_to_site()
是必需的。
一种解决方案是运行:
upload_result_to_site(processed_result)
在“后台”中的运行方式与在UNIX上在后台运行进程的方式相同。
我可以在后台运行整个脚本(通过os.popen3
或subprocess
),也可以使用守护程序。但是我想要最简单的解决方案。我找不到使用子进程仅调用脚本的一部分(单个函数)的方法
multiprocessing.Pool.map()
可以使用,但是它创建的进程必须在某个时候加入和终止,否则子进程的数量将继续增长。
有一种简单的方法吗?
更新:目前,我正在使用以下解决方法:
for data_item in data_items:
processed_result=process_data(data_item); #this takes time T0
os.system("myscript.py upload_result_to_site processed_result &")
其中myscript.py
是脚本的名称,并且适当的处理程序位于__name__==__main__
中。
(理论上的)缺点是,这可能仅适用于Unix。由于我的服务器运行的是Unix,这对我来说很好。如果有人有更好的解决方案,请回答。
答案 0 :(得分:0)
真正长期的简单解决方案是为自己创建所需的基本构建块。您的脚本正在做两个非常不同的事情。
“自然”的解决方案是将您的脚本变成一个模块,该模块仅提供不同的服务。
然后,您可以编写一个或多个导入该模块的脚本,然后您可以使用popen3 / subprocess简单地调用一个仅对单个结果进行 upload 的小脚本。
答案 1 :(得分:0)
为什么不只是做这样的事情?
from multiprocessing import Pool
with Pool() as pool:
for result in pool.imap_unordered(process_data, data_items)
upload_result_to_site(result)
这将导致启动多个进程(Python根据您拥有的内核进行猜测),并在子进程中执行process_data
。然后将结果返回到主过程,在此过程中,结果将作为处理完成而上传
还请注意,发送到子作业或从子作业中检索时,“数据”为pickled
,因此需要与此兼容。