在数据文件夹上同时运行4个Python脚本实例
我们有一个文件夹里有50个数据文件(下一代DNA序列),需要通过运行一个Python脚本来转换每一个文件。每个文件运行这个脚本需要5个小时,而且这个脚本是单线程的,主要消耗CPU资源(CPU核心的使用率达到99%,而磁盘的读写几乎没有)。
因为我有一台4核的电脑,所以我想同时运行4个这个脚本实例,这样可以大大加快处理速度。
我想我可以把数据分成4个文件夹,然后同时在每个文件夹上运行以下的bash脚本:
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的建议。再次感谢!
4 个回答
试试这个:
#!/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 进程,并把它们放到后台运行。当这四个进程都完成后,它会继续处理接下来的四个文件。虽然这样做没有一直保持四个进程同时运行那么高效,但如果所有进程的运行时间差不多,这样的效果也差不多。
另外,拜托,千万不要那样使用 ls
的输出。直接用标准的通配符匹配就可以,比如 for files in *.txt; do ...; done
。
你可以使用 multiprocessing
这个模块。我想你可能有一堆文件需要处理,还有一个函数要对每个文件进行操作。那么你可以像这样简单地使用一个工作池:
from multiprocessing import Pool, cpu_count
pool = Pool(processes=cpu_count)
pool.map(process_function, file_list, chunksize=1)
如果你的 process_function
函数没有返回值,那你就可以直接忽略它的返回值。
看看这个 xargs
命令。它的 -P
选项可以让你设置并行处理的程度。简单来说,你可以通过这个选项来控制同时运行多少个任务。具体来说,像下面这样写应该能满足你的需求:
ls files* | awk '{print $1,$1".out"}' | xargs -P 4 -n 2 python fastq_groom.py