利用parallel实现并发
摘要
运行大规模重测序数据的比对,需要大量计算资源,一次性提交到服务器造成服务器负载过大,利用循环一次提交单个任务运行速度较慢,指定线程数目的并行是较为理想的解决方案。
初探
找到如下函数(功能)
# 当前shell pid
$$
# 获取当前shell子进程数目
pstree -p $$ | grep speedseq | wc -l
简单实现
workspace=/storage-04/yin/black_bone
ref=/storage-01/poultrylab1/yin/sywgj
for i in `cat all_sra.txt`;
do
speedseq align -t 20 -R "@RG\tID:${i}\tSM:${i}\tLB:lib${i}" ${ref}/cau_silkie_chicken.fasta ${workspace}/${i}_1.fastq.gz ${workspace}/${i}_2.fastq.gz -o ${i} &
n=`ps -ef | grep "speedseq align" | wc -l`
while [ $n -ge 10 ];
do
sleep 10s
n=`ps -ef | grep "speedseq align" | wc -l`
done
done
# last 10 job submit finished, above finished, so this bash script won't wait last 10 job. should add `wait`
wait
解释
每次for循环给speedseq 20线程,当前shell后台speedseq的线程数大于等于10,就等待并再次刷新线程数,每过10s判断一次。
错误
经过测试,最后会留下十个任务未运行,不知道哪出问题了。希望知道的大佬勘误!
纠错
找到原因是因为没有等待最后是个任务运行结束
优化
利用parallel简化代码,且不易出错
time parallel -N1 -j 10 speedseq align -t 20 -R "@RG'\'tID:{}'\'tSM:{}'\'tLB:lib{}" -o {} /storage-01/poultrylab1/zhaoqiangsen/GenomeAssembly/chicken/history_asm/Scaffold_13.fasta {}_1.fastq.gz {}_2.fastq.gz ::: `ls *_1*.gz | grep -v 1r | awk -F "_1" '{print $1}'`
解释
time 用来计时,-N1表示一次接受一个参数,-j10表示同时运行十个任务,:::要传入的参数,中间是要运行的子命令,可以根据服务器资源指定单个线程数