美文网首页
Shell 使用多线程提交任务-FIFO

Shell 使用多线程提交任务-FIFO

作者: caokai001 | 来源:发表于2020-12-01 15:20 被阅读0次

参考:

学习snakemake,三步轻松搭建生信流程!
linux shell 多线程执行程序
[Linux 1] Shell“ 多线程”,提高工作效率

目前snakemake 对整合生信流程比较友好,shell流程写惯了也还行。感觉在没有作业提交系统的服务器上,使用snakemake 可以很好的控制核心数目,保证服务器可能正常运行,而不是超负荷状态。shell脚本一般都是for循环进行批量,假如存在几百个样本一次批量提交到后台,可能会卡死。

  • 发现shell也可以支持多线程提交,就记录下来。
  • Shell中并没有真正意义的多线程,要实现多线程可以启动多个后端进程,最大程度利用cpu性能

1 顺序执行的代码

#!/bin/bash
date
for i in `seq 1 5`
do
{
    echo "sleep 5"
    sleep 5
}
done
date

结果

Tue Dec  1 14:27:49 CST 2020
sleep 5
sleep 5
sleep 5
sleep 5
sleep 5
Tue Dec  1 14:28:14 CST 2020



2 并行代码

  • 使用'&'+wait 实现“多进程”实现
#!/bin/bash
date
for i in `seq 1 5`
do
{
    echo "sleep 5"
    sleep 5
} &
done
wait  ##等待所有子后台进程结束
date

结果

Tue Dec  1 14:29:01 CST 2020
sleep 5
sleep 5
sleep 5
sleep 5
sleep 5
Tue Dec  1 14:29:06 CST 2020



3 对于大量处理任务如何实现启动后台进程的数量可控?

  • 简单的方法可以使用2层for/while循环实现,每次wait内层循环的多个后台程序执行完成。
  • 但是这种方式的问题是,如果内层循环有“慢节点”可能导致整个任务的执行执行时间长。
#!/bin/bash
date
for i in `seq 1 3`
do
{


for j in `seq 1 5`
do
{
    echo "$i : sleep 5"
    sleep 5
} &
done
wait  ##等待所有子后台进程结束


}
done
date

结果

Tue Dec  1 14:16:51 CST 2020
1 : sleep 5
1 : sleep 5
1 : sleep 5
1 : sleep 5
1 : sleep 5
2 : sleep 5
2 : sleep 5
2 : sleep 5
2 : sleep 5
2 : sleep 5
3 : sleep 5
3 : sleep 5
3 : sleep 5
3 : sleep 5
3 : sleep 5
Tue Dec  1 14:17:06 CST 2020

4.使用命名管道(fifo)实现每次启动后台进程数量可控。

: 经常需要修改的参数:

  • thread_num=5 # 定义最大线程数
  • 修改自己的任务


    image.png
#!/bin/bash
# bam to bed

start_time=`date +%s`  #定义脚本运行的开始时间

tmp_fifofile="/tmp/$$.fifo"
mkfifo $tmp_fifofile   # 新建一个FIFO类型的文件
exec 6<>$tmp_fifofile  # 将FD6指向FIFO类型
rm $tmp_fifofile  #删也可以,

thread_num=5  # 定义最大线程数

#根据线程总数量设置令牌个数
#事实上就是在fd6中放置了$thread_num个回车符
for ((i=0;i<${thread_num};i++));do
    echo
done >&6

for i in `seq 1 10 ` # 需要处理的所有情况
do
    # 一个read -u6命令执行一次,就从FD6中减去一个回车符,然后向下执行
    # 当FD6中没有回车符时,就停止,从而实现线程数量控制
    read -u6
    {
    
    ### Start 输入自己的命令
        echo "great" # 可以用实际命令代替
        echo "$i is running"
        sleep $i
    ### End 输入自己的命令
        
        
        echo >&6 # 当进程结束以后,再向FD6中加上一个回车符,即补上了read -u6减去的那个
    } &
done

wait # 要有wait,等待所有线程结束

stop_time=`date +%s` # 定义脚本运行的结束时间
echo "TIME:`expr $stop_time - $start_time`" # 输出脚本运行时间

exec 6>&- # 关闭FD6
echo "over" # 表示脚本运行结束

结果:

great
1 is running
great
great
2 is running
3 is running
great
4 is running
great
5 is running
great
6 is running
great
7 is running
great
8 is running
great
9 is running
great
10 is running
TIME:15
over

思考

  • 一般情况下集群有PBS系统,不需要这么麻烦限制任务提交数目,或者CPU核心数目
  • snakemake比较容易解决核心问题

相关文章

  • Shell 使用多线程提交任务-FIFO

    参考: 学习snakemake,三步轻松搭建生信流程![https://zhuanlan.zhihu.com/p/...

  • PySparkSQL脚本模板

    PySpark模板分为shell脚本和python脚本两部分,通过shell脚本提交spark任务。 shell脚...

  • iOS基础之GCD

    GCD简介 GCD提供并管理了FIFO任务队列,提交到任务队列中的任务(Task)在一个线程池中执行。 同步syn...

  • Linux之shell脚本编程

    Linux之shell脚本编程 主要内容: • Vim 编辑器• Shell 脚本• 任务提交 Vim 编辑器 V...

  • 有名管道

    shell mkfifo fifo1 [名称] 建立一个有名管道 cat < fifo1 用cat读取有...

  • GCD(调度队列任务)

    GCD提供和管理FIFO队列,应用程序可以在块对象的形式提交的任务。提交给调度队列的块在系统完全由系统管理的...

  • shell多进程执行任务

    脚本 输出内容: shell本身是不支持多线程的,但是我们可以把要执行的任务放到后台执行,加入任务中有多个任务就用...

  • spark Shell 启动和提交任务

  • iOS 多线程- pThread和NSThread

    本文内容:多线程的优缺点多线程实现技术方案如何使用pThread实现多线程如何使用NSthread执行任务、设置优...

  • Java面试题——多线程

    Java面试题——多线程 1,什么是线程池? 线程池是多线程的一种处理方式,处理过程中将任务提交给线程池,任务执行...

网友评论

      本文标题:Shell 使用多线程提交任务-FIFO

      本文链接:https://www.haomeiwen.com/subject/hqlswktx.html