Многопроцессорная и многопоточность - PullRequest
5 голосов
/ 27 февраля 2012

Я задавал подобный вопрос раньше, но не получил никакого полезного ответа, поэтому я попытаюсь прояснить ситуацию.

То, что я ищу, - это запустить многопоточный или предпочтительно многопроцессорный подход к определенной команде linux,Если кто-то знаком с Picard , я хочу запустить более раннюю версию для файла bam и одновременно запустить более новую версию для того же файла bam.Идея состоит в том, чтобы проверить, насколько быстрее новая версия и дает ли она тот же результат.

Моя главная проблема заключается в том, что я понятия не имею, как реализовать многопроцессорную обработку по команде Popen.Например,

cmd1 = ['nice', 'time', 'java', '-Xmx6G', '-jar', '/comparison/old_picard/MarkDuplicates.jar', 'I=/comparison/old.bam', 'O=/comparison/old_picard/markdups/old.dupsFlagged.bam', 'M=/comparison/old_picard/markdups/old.metrics.txt', 'TMP_DIR=/comparison', 'VALIDATION_STRINGENCY=LENIENT', 'ASSUME_SORTED=true']
cmd2 = ['nice', 'time', 'java', '-Xmx6G', '-jar', '/comparison/new_picard/MarkDuplicates.jar', 'I=/comparison/new.bam', 'O=/comparison/new_picard/markdups/new.dupsFlagged.bam', 'M=/comparison/new_picard/markdups/new.metrics.txt', 'TMP_DIR=/comparison', 'VALIDATION_STRINGENCY=LENIENT', 'ASSUME_SORTED=true']

c1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE)
c2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE)

И тогда у меня есть функция таймера:

def timeit(c):
    past = time.time()
    results = [c.communicate()]
    present = time.time()
    total = present - past
    results.append(total)
    return results

Что я хочу сделать, это:

p = Process(target=timeit, args=(c1,c2))
p.start()
p.join()

Однако я получаю "объект Popenне повторяемая ошибкаУ кого-нибудь есть идея получше, чем у меня сейчас?Я не хочу уходить в совершенно другом направлении, только чтобы ударить другую стену.Итак, я хочу запустить c1 на одном процессоре и c2 на другом одновременно, пожалуйста, помогите!

Ответы [ 2 ]

4 голосов
/ 27 февраля 2012

Вместо передачи подпроцесса. Откройте (который будет запускать их последовательно, а не параллельно, когда он впервые определен), передайте команду :

import time
import subprocess
from multiprocessing import Process

cmd1 = ['nice', 'time', 'java', '-Xmx6G', '-jar', '/comparison/old_picard/MarkDuplicates.jar', 'I=/comparison/old.bam', 'O=/comparison/old_picard/markdups/old.dupsFlagged.bam', 'M=/comparison/old_picard/markdups/old.metrics.txt', 'TMP_DIR=/comparison', 'VALIDATION_STRINGENCY=LENIENT', 'ASSUME_SORTED=true']
cmd2 = ['nice', 'time', 'java', '-Xmx6G', '-jar', '/comparison/new_picard/MarkDuplicates.jar', 'I=/comparison/new.bam', 'O=/comparison/new_picard/markdups/new.dupsFlagged.bam', 'M=/comparison/new_picard/markdups/new.metrics.txt', 'TMP_DIR=/comparison', 'VALIDATION_STRINGENCY=LENIENT', 'ASSUME_SORTED=true']

def timeit(cmd):
    print cmd
    past = time.time()
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    results = [p.communicate()]
    present = time.time()
    total = present - past
    results.append(total)
    return results

p1 = Process(target=timeit, args=(cmd1,))
p2 = Process(target=timeit, args=(cmd2,))

for p in (p1, p2):
    p.start()
for p in (p1, p2):
    p.join()

ETA: в то время какПриведенное выше решение является способом сделать многопроцессорную работу в целом, @Jordan совершенно прав, что вы не должны использовать этот подход для двух версий программного обеспечения.Почему бы не запустить их последовательно?

0 голосов
/ 27 февраля 2012

Я думаю, что-то вроде этого должно работать:

p1 = Process(target=timeit, args=(c1,))
p2 = Process(target=timeit, args=(c2,))
p1.start()
p2.start()
p1.join()
p2.join()

Я не знаю, где ваша ошибка итерации (какая строка?).

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

...