2014-12-19 4 views
0

У меня есть n файлы для анализа отдельно и независимо друг от друга с тем же сценарием Python analysis.py. В сценарии оболочек wrapper.py, я перебираю эти файлы и вызвать analysis.py как отдельный процесс с subprocess.Popen:python, подпроцесс: запуск нового процесса, когда один (в группе) завершен

for a_file in all_files: 
    command = "python analysis.py %s" % a_file 
    analysis_process = subprocess.Popen(
              shlex.split(command), 
              stdout=subprocess.PIPE, 
              stderr=subprocess.PIPE) 
    analysis_process.wait() 

Теперь я хотел бы использовать все к ядер процессора моей машины, чтобы скорость весь анализ. Есть ли способ всегда иметь k-1 запущенных процессов, пока есть файлы для анализа?

+3

[ 'multiprocessing.Pool'] (https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers);) –

+0

ли 'analy.py' тот же скрипт? –

+0

да! это так же просто, как в приведенном выше примере. Я посмотрю на multiprocessing.Pool, спасибо :) –

ответ

3

Это описывает, как использовать multiprocessing.Pool, которая существует именно для решения этих задач:

from multiprocessing import Pool, cpu_count 

# ... 
all_files = ["file%d" % i for i in range(5)] 


def process_file(file_name): 
    # process file 
    return "finished file %s" % file_name 

pool = Pool(cpu_count()) 

# this is a blocking call - when it's done, all files have been processed 
results = pool.map(process_file, all_files) 

# no more tasks can go in the pool 
pool.close() 

# wait for all workers to complete their task (though we used a blocking call...) 
pool.join() 


# ['finished file file0', 'finished file file1', ... , 'finished file file4'] 
print results 

Добавление комментария Джоэла упоминая общий ловушкой:

Убедитесь, что функция вы передаете pool.map () содержит только объекты, определенные на уровне модуля. Многопроцессорность Python использует pickle для передачи объектов между процессами, а у рассола есть проблемы с такими вещами, как функции, определенные во вложенной области.

The docs for what can be pickled

+0

Это довольно аккуратно! Спасибо. Поэтому в основном, чтобы адаптировать его к моему делу, я просто поместил вызов 'subprocess.Popen' в вышеуказанную функцию' process_file', и все сделано. Правильно? –

+0

@RickyRobinson Nope, процессы открываются неявно в пуле. Вам не нужно открывать процессы самостоятельно. Вам нужно обработать файл, и это все :) –

+1

Я только упоминаю об этом, потому что это кажется довольно распространенным, но убедитесь, что функция, которую вы передаете в 'pool.map()', содержит только объекты, которые определены в * уровень модуля *. Многопроцессорность Python использует 'pickle' для передачи объектов между процессами, а у рассола есть проблемы с такими вещами, как функции, определенные во вложенной области. См. Документацию для [того, что можно мариновать] (https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled) –

Смежные вопросы