如何在“后台”中运行脚本的一部分(单个功能)?

时间:2019-01-23 14:26:48

标签: python multithreading server multiprocessing

我在具有以下基本结构(伪代码)的服务器上运行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

基本约束是:

  1. data_items是一个(大)数据列表
  2. process_data()使用了很多CPU。
  3. upload_result_to_site()占用的CPU很少。
  4. T0 = 5*T1(大约)

现在,我的服务器时间有限,我想将所有时间用于CPU密集型process_data(),而不是upload_result()上。不幸 upload_result_to_site()是必需的。

一种解决方案是运行:

upload_result_to_site(processed_result)

在“后台”中的运行方式与在UNIX上在后台运行进程的方式相同。

我可以在后台运行整个脚本(通过os.popen3subprocess),也可以使用守护程序。但是我想要最简单的解决方案。我找不到使用子进程仅调用脚本的一部分(单个函数)的方法

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,这对我来说很好。如果有人有更好的解决方案,请回答。

2 个答案:

答案 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,因此需要与此兼容。