2012-01-23 3 views
5

У нас есть папка с 50 файлами данных (последовательности ДНК следующего поколения), которые необходимо преобразовать, запустив скрипт python для каждого из них. Скрипт занимает 5 часов в файле, он однопоточный и в основном связан с ЦП (ядро процессора работает на 99% с минимальным дисковым IO).Запустите 4 параллельных экземпляра сценария python в папке с файлами данных

Поскольку у меня 4-ядерная машина, я бы хотел запустить 4 экземпляра этого сценария сразу, чтобы значительно ускорить процесс.

Я предполагаю, что я мог бы разделить данные на 4 папки и запустить следующий Баш скрипт на каждой папке, в то же время:

files=`ls -1 *` 
for $file in $files; 
do 
    out = $file+=".out" 
    python fastq_groom.py $file $out 
done 

Но должно быть лучший способ запустить его на одну папку , Мы можем использовать Bash/Python/Perl/Windows для этого.
(К сожалению, делает сценарий поддерживает многопоточность это за то, что мы можем сделать)


Использование @phs xargs решение было самым простым способом для нас, чтобы решить эту проблему. Тем не менее мы просим оригинального разработчика реализовать @ Björn ответ. Еще раз спасибо!

+2

Использование в команде ls обратных кавычках, и присвоение значения переменного для загрузки, являются частыми антипаттернами. Он будет разбиваться на имена файлов с пробелами, и он будет разбит, если у вас есть подкаталоги. Правильная идиома - 'для файла в *' - обратите внимание также на отсутствие знака доллара при присвоении имени переменной; вы используете знак доллара при интерполяции переменной. См. Также http://partmaps.org/era/unix/award.html#ls – tripleee

+0

@triplee Спасибо за подсказку –

ответ

1

Посмотрите на xargs. Опция -P предлагает настраиваемую степень параллелизма. В частности, то, как это должно работать для вас:

ls files* | awk '{print $1,$1".out"}' | xargs -P 4 -n 2 python fastq_groom.py 
+1

, это сломается с файлами с пробелами в их именах и, возможно, с другими гадостями, такими как новые строки и т. П. – SiegeX

7

Вы можете использовать multiprocessing -модуль. Я полагаю, у вас есть список файлов для обработки и функция для вызова каждого файла. Тогда вы могли бы просто использовать рабоче-бассейн, как это:

from multiprocessing import Pool, cpu_count 

pool = Pool(processes=cpu_count) 
pool.map(process_function, file_list, chunksize=1) 

Если ваш process_function не возвращает значение, вы можете просто игнорировать возвращаемое значение.

1

Дайте этому выстрел:

#!/bin/bash 

files=(*) 
for((i=0;i<${#files[@]};i+=4)); do 
    { 
    python fastq_groom.py "${files[$i]}" "${files[$i]}".out & 
    python fastq_groom.py "${files[$i+1]}" "${files[$i+1]}".out & 
    python fastq_groom.py "${files[$i+2]}" "${files[$i+2]}".out & 
    python fastq_groom.py "${files[$i+3]}" "${files[$i+3]}".out & 
    } 
done 

следующие путы все файлы в массив с именем files. Затем он выполняет и выполняет четыре процесса python в первых четырех файлах. Как только все четыре процесса этих процессов завершены, он выполняет следующие четыре. Это не так эффективно, как всегда, когда очередь идет 4, но если все процессы занимают примерно столько же времени, это должно быть довольно близко к этому.

Кроме того, пожалуйста, пожалуйста, не используйте вывод ls. Просто используйте стандартные универсализации как в for files in *.txt; do ...; done

0

Если GNU Parallel вы можете сделать:

parallel python fastq_groom.py {} {}.out ::: files* 

Он будет делать правильно, порождая работу на ядро, даже если имена файлов имеют место, ', или "в них. Он также гарантирует, что вывод с разных заданий не смешивается вместе, поэтому, если вы используете выход, вы гарантированно получите половину строки от двух разных заданий.

GNU Параллель - это общий параллелизатор и позволяет легко запускать задания параллельно на одном компьютере или на нескольких компьютерах, к которым у вас есть доступ ssh.

Если у вас есть 32 различных заданий, которые вы хотите работать на 4-х процессоров, прямо вперед способ распараллеливания является выполнение 8 заданий на каждом CPU:

Simple scheduling

GNU Parallel вместо порождает новый процесс, когда один заканчивается - поддержание процессоров активным и тем самым экономя время:

GNU Parallel scheduling

Установка

Если GNU Parallel не упакован для вашего дистрибутива, вы можете выполнить личную установку, которая не требует доступа root. Это может быть сделано в течение 10 секунд, делая это:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash 

Для других вариантов установки см http://git.savannah.gnu.org/cgit/parallel.git/tree/README

Подробнее

Другие примеры: http://www.gnu.org/software/parallel/man.html

смотреть интро видео: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Прогулка по t он учебник: http://www.gnu.org/software/parallel/parallel_tutorial.html

Зарегистрируйтесь на список адресов электронной почты, чтобы получить поддержку: https://lists.gnu.org/mailman/listinfo/parallel