我正在尝试使用python并行运行程序列表。
为了抽象我正在这样做的真正原因,我编写了一个名为fake_program.py
的小命令行程序,该程序接受一个文本文件作为参数,该文件包含由逗号分隔的任意数字列表。程序添加数字并打印结果。
fake_program.py
:
import argparse
##parse arguments from command line
parser = argparse.ArgumentParser()
parser.add_argument('filename', type=str)
args = parser.parse_args()
## read data file
with open(args.filename) as f:
numbers = f.read()
## process and add the numbers
numbers = numbers.split(',')
numbers = [int(i) for i in numbers]
print reduce(lambda x, y: x + y, numbers)
示例输入文件:
data_file_1.txt
包含:
1, 2, 3
data_file2.txt
包含
4, 5, 6
data_file3.txt
包含
7, 8, 9
使用方法:
$ python fake_program.py data_file1.txt
output
:
6
我的目标是通过fake_program.py
并行处理这三个文件(或任意数量的类似文件)。请注意,对于这个简单的示例,只需运行fake_program.py
的单独实例就可以处理所有数据。但是,我真正运行的程序计算量很大,并且在大约8个实例中变得没有响应。由于我通过程序运行了大约400个数据文件,并且每个数据文件最多需要5分钟才能处理,因此最好引入一个Queue
,以便(比如说)可以一次处理5个数据文件一个完成另一个开始。
到目前为止,这是脚本:
from subprocess import Popen, PIPE
from threading import Thread
import Queue
from multiprocessing import cpu_count
import glob
def run1(q, fle):
"""
Process 1 file
:return:
"""
args = ['python', 'fake_program.py', '"{}"'.format(fle)]
proc = Popen(args, stdin=PIPE, stdout=PIPE,
stderr=PIPE, shell=False)
q.put(proc, block=True)
def run_all(files):
"""
"""
number_of_processes = cpu_count()
q = Queue.Queue(number_of_processes)
result = []
for fle in files:
t = Thread(target=run1, args=(q, fle))
t.start()
q.join()
result.append(q.get())
return result
if __name__=='__main__':
working_directory = </my/working/directory>
data_files = glob.glob(working_directory+'\*.txt')
print data_files
print run_all(data_files)
这个程序目前只是悬而未决。有没有人对如何实现这种并行性有任何建议?
答案 0 :(得分:-2)
也许使用multiprocessing.Pool而不是Queue。如果您的作业是异步的,那么使用起来非常简单。此外,如果您的子进程抛出异常,Python多处理可能不够智能,无法将其返回到主进程。在这种情况下,我已经看到过。