shell控制多并发数量——脚本方法

说明

多并发我之前已经说过了,不清楚的可以参考:
但有一个问题,如果运行了好多个这样的脚本,都没释放,直到,达到系统设置的最大fd数,就打不开文件了。 也就是说,shell多进程,只有fd要释放这个潜在的危险,其它的风险都没有。但如果有fd要释放的,而没有弄限制,就容易出问题。 ps:只要没有涉及到fd要释放的,就不需要折腾,弄控制并发的步骤。
啥?啥是fd? 下面放个图简单说明一下,具体的自行百度吧。
在这里插入图片描述

代码如下

代码(附带解释)

#!/bin/bash
time=`echo 执行前时间$(date +"%H:%M.%S")`
# 脚本执行前写空该文件
>$0.log 
#$$是当前脚本的进程号,后面fifo是起个名而已
tmp_fifofile="$$.fifo"
# 创建命名管道符
mkfifo $tmp_fifofile
# exec <> 是把管道符的标准输入输出和6号fd绑定,6是自定义的,随便取(取值注意:0是标准输入,1是标准输出,2是错误输出)
#fd 就是 文件句柄(每打开一个文件,就会自动生成一个fd)
#exec 6<>pipe文件  就是让6号文件描述符有管道的所有特性
exec 6<>$tmp_fifofile
rm $tmp_fifofile
thread_num=255

#create key
for ((i=0;i<${thread_num};i++));do
    echo
#这个echo是输入thread_num个空行到 fd里
#就相当于管道了有255个空行, 也就是最大只能并发255个进程
#由下面那个for去读取空行,读取完,然后再写进去个空行
done >&6 #这是子线程清除
for i in {1..1000}
#注,这个取值如果大于上面定义的区间,就会导致:第一批瞬间读取了255个空行,里面已经没有了内容可以读了,就会管道就会堵塞,直到,每个进程的运行完,再写进去一个空行,才能继续从管道里读取一个,接着再分叉一个进程
#假如有1000个要并发的进程,你要控制最多只能运行255个的时候,255个运行完了,不写入空行到里面,就会一直阻塞,剩下745就会一直阻塞(运行不了,直到你给脚本发一个kiil 9信号,结束),因为这个脚本有写,所以就是说前面255执行完了,需要等255中执行完毕释放后255以后的才会得到执行。
do
# 每次从管道里读取一个空行,如循环一次后还剩254个空行可以消费(上面定义的同时最多可以消费255个)
read -u6 #如果不能理解,下面有个图单独说明这个
{
 ip="192.168.198.$i"
 echo $ip
 a=`ping -c 100 $ip|grep "100% packet loss"`
 # 判断ping是否有上面100%这些内容,如果有则up。
 if [ "$a" == "" ] 
 then
  echo "$ip network is up" >> $0.log
 else
  echo "$ip network is error" >>$0.log

 fi
 #echo >&6:{}&中的代码执行完,再写入一个空行
 echo >&6
} &

done

wait
echo $time 
echo 全部后台完成时间$(date +"%H:%M.%S")
# exec 6>&-;exec6<&- 都行,起释放作用,必须要有!
exec 6>$-

在这里插入图片描述
在这里插入图片描述
木桶令牌说明如下:
在这里插入图片描述

在这里插入图片描述

纯代码

#!/bin/bash
time=`echo 执行前时间$(date +"%H:%M.%S")`
>$0.log

tmp_fifofile="$$.fifo"
mkfifo $tmp_fifofile
exec 6<>$tmp_fifofile
rm $tmp_fifofile
thread_num=255

#create key
for ((i=0;i<${thread_num};i++));do
    echo
done >&6
for i in {1..1000}
do
read -u6
{
 ip="192.168.198.$i"
 echo $ip
 a=`ping -c 100 $ip|grep "100% packet loss"`
 if [ "$a" == "" ]
 then
  echo "$ip network is up" >> $0.log
 else
  echo "$ip network is error" >>$0.log

 fi
echo >&6
} &
done


wait
echo $time 
echo 全部后台完成时间$(date +"%H:%M.%S")
exec 6>$-

echo >&6 放错位置说明

正确位置

在这里插入图片描述

echo >&6正确存放位置是放在{}&括号中最后位置的,执行结果比较慢,上面说过,如果定义了1-255,一次最大只能并发255个,后面的需要前面255执行完毕释放以后才能依次执行,所以会看到明显停顿。
在这里插入图片描述
这样就会导致执行时间过慢,以ping -c 100 $ip 为例,执行时间就是:1000/255*100 ,单位是秒,所以执行上面脚本大概需要:1000/255*100/60=6.5359分钟
在这里插入图片描述

错误之——位置错误

在这里插入图片描述

echo >&6如果放在{}&外面的话,就会导致,前面定义的1-255区间就没用,执行的时候,1000个直接一下子就全部放后台执行了,导致的后果就是,线程溢出,这个脚本没有执行完,其他命令就会执行无法返回结果或者返回结果很慢。
在这里插入图片描述
但执行速度明显比放里面提升了很多。理论时间是:1000/1000*100 秒,至于有多了的时间,可能是性能不足导致的运行延迟。
在这里插入图片描述

错误之——直接注释掉

我加 echo >6& 后系统不判断 一个c的地址,有多少都给我加, 但 echo >&6 注释以后,系统就会判断一个c的地址,超出一个c范围后就给我提示并脚本卡主。
原因 未知!
在这里插入图片描述

一个实例解释

在这里插入图片描述
分别解释上面可能存在的疑问
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__ 返回首页