我有一个文件名列表,我需要在它们上运行外部程序( lastz 程序)。外部程序需要两个输入文件并生成一个输出文件,根据输入文件的大小需要1-2个小时。
我的下面的程序一次运行一个外部程序。
import subprocess
def run_lastz(input1, input2, output):
cmd_string = "lastz '{}'[multiple] {} --ambiguous=iupac --ambiguous=n --format=sam --output='{}' --chain --gapped ".format(file1, file2, output)
print(cmd_string)
process = subprocess.Popen(cmd_string, shell=True, stdout=subprocess.PIPE)
process.wait()
file_name_list = ['1.txt', '2.txt', '3.text', '15.txt', '111.txt', '31.txt', '41.txt', '50.txt', '1011.txt']
for file1 in file_name_list:
for file2 in file_name_list:
if file1 != file2:
out_file = '{}__{}.out'.format(file1, file2)
run_lastz(file1, file2, out_file)
现在我正在努力提高运行外部程序的速度,这可以通过在并行模式下运行多个这样的程序来实现。
我认为多线程或多处理可以解决上述问题,我对多线程或多处理非常陌生。需要一些帮助。我的目标是一次只运行8到12个外部程序,然后完成下一组。
答案 0 :(得分:1)
使用多处理,而不是多线程,因为它有GIL问题。
关于multiprocessing here的更多信息!
为了限制进程数,我们需要在多处理中使用Pool类。
检查以下代码:
from multiprocessing import Pool
def run_lastz(file_tuple):
f1,f2,out = file_tuple
print " Working with input -",f1,f2,out
print "----------------------------------"
if __name__ == '__main__':
# Start 10 worker processes
pool = Pool(processes=10)
#Then create a list of input list [(1.txt,2.txt,1_2.out),(2.txt,3.txt,2_3.out)....]
file_name_list = ['1.txt', '2.txt', '3.text', '15.txt', '111.txt', '31.txt', '41.txt', '50.txt', '1011.txt']
f_list =[]
for file1 in file_name_list:
for file2 in file_name_list:
if file1 != file2:
out_file = '{}__{}.out'.format(file1, file2)
t_list =(file1,file2,out_file)
f_list.append(t_list)
#Map input list with target function
pool.map(run_lastz, f_list)
注意:
出于演示目的,我已从run_lastz
功能中删除了原始代码。理解上述代码并能够运行后,修改run_lastz
函数的功能。
此外,我通过上述链接获得更详细的了解是我的谦虚请求。