5 python multithreading subprocess multiprocessing
之前我问了一个类似的问题,但没有得到有用的答复,所以我会努力让事情变得更清楚.
我正在寻找的是对某个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)
Run Code Online (Sandbox Code Playgroud)
然后我有一个计时器功能:
def timeit(c):
past = time.time()
results = [c.communicate()]
present = time.time()
total = present - past
results.append(total)
return results
Run Code Online (Sandbox Code Playgroud)
我想要做的是:
p = Process(target=timeit, args=(c1,c2))
p.start()
p.join()
Run Code Online (Sandbox Code Playgroud)
但是我得到"Popen object is iterable"错误.有没有人比我现在拥有更好的主意?我不想在一个完全不同的方向走,只能撞到另一面墙.总之我想在一个cpu上运行c1而在另一个c2上同时运行c2,请帮忙!
不要传递 subprocess.Popen (它将在首次定义时串行运行而不是并行运行),而是传递命令:
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()
Run Code Online (Sandbox Code Playgroud)
ETA:虽然上述解决方案是一般进行多处理的方法,但 @Jordan 完全正确,您不应该使用这种方法来对两个版本的软件进行计时。为什么不按顺序运行它们呢?