Shell脚本并发及并发数的控制

https://www.jianshu.com/p/701952ffb755ruby

正常状况下,Shell脚本是串行执行的,一条命令执行完才会执行接下来的命令。以下代码:bash

# !/bin/bash for i in `seq 1 10` do echo $i done echo "----end----" 

脚本执行的结果以下:服务器

1 2 3 4 5 6 7 8 9 10 ----end---- 

echo $1 命令串行执行,若是命令耗时较长致使总时间较长。若是命令之间没有互相依赖关系时,可让命令并行执行,并行执行的方法就是在命令后加上 & 符号。并发

# !/bin/bash for i in `seq 1 10` do echo $i & done echo "----end----" 

脚本执行的结果以下:spa

1 2 3 5 4 ----end---- 10 7 8 9 6 

能够看到,这样不能保证命令的执行顺序,有的时候须要保证for循环全部命令执行完后再向后执行接下来的命令。可使用 wait 实现code

# !/bin/bash for i in `seq 1 10` do echo $i & done wait echo "----end----" 

脚本执行的结果以下:资源

1 2 3 6 9 10 4 5 7 8 ----end---- 

问题尚未结束,当须要并行执行的命令数量特别多的时候,特别是执行命令的资源占用较多时,直接用 & 实现并行容易将服务器资源占用打满,影响其余程序运行。
使用管道和令牌原理实现并发控制。get

#!/bin/bash # Step1 建立有名管道 [ -e ./fd1 ] || mkfifo ./fd1 # 建立文件描述符,以可读(<)可写(>)的方式关联管道文件,这时候文件描述符3就有了有名管道文件的全部特性 exec 3<> ./fd1 # 关联后的文件描述符拥有管道文件的全部特性,因此这时候管道文件能够删除,咱们留下文件描述符来用就能够了 rm -rf ./fd1 # Step2 建立令牌 for i in `seq 1 2`; do # echo 每次输出一个换行符,也就是一个令牌 echo >&3 done # Step3 拿出令牌,进行并发操做 for line in `seq 1 10`; do read -u3 # read 命令每次读取一行,也就是拿到一个令牌 { echo $line echo >&3 # 执行完一条命令会将令牌放回管道 }& done wait exec 3<&- # 关闭文件描述符的读 exec 3>&- # 关闭文件描述符的写
做者:不智鱼 连接:https://www.jianshu.com/p/701952ffb755 来源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。
相关文章
相关标签/搜索