使用Python的并行编程工具来处理数据文件

时间:2017-09-08 19:43:57

标签: python multithreading parallel-processing

我正在尝试使用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)

这个程序目前只是悬而未决。有没有人对如何实现这种并行性有任何建议?

1 个答案:

答案 0 :(得分:-2)

也许使用multiprocessing.Pool而不是Queue。如果您的作业是异步的,那么使用起来非常简单。此外,如果您的子进程抛出异常,Python多处理可能不够智能,无法将其返回到主进程。在这种情况下,我已经看到过。