一、怎么理解shell并发:
当咱们在执行一个for循环时,假设这个for循环须要循环500次,每循环一次就须要1秒,当这个for循环的脚本执行完毕时,就须要500秒,这样看效率有些低(尤为在量级高的时候,会更明显),因此咱们须要shell脚本的for循环不管循环多少次,让它们同时执行,不须要按顺序循环,这就是shell脚本的并发。
二、如何实现shell脚本并发:
实现很是简单,就是在循环体的{}后面加上一个&符号,表明每次循环体的命令都放入后台运行
三、经典实例:
判断192.168.80.0/24网络,当前在线的主机数以及IPshell
#!/bin/bash . /etc/init.d/functions cmd="ping -c 2" for ((i=1;i<=254;i++));do { $cmd 192.168.80.$i &>/dev/null if [ $? = 0 ];then action "192.168.80.$i" /bin/true fi }& #将{}循环体放入后台执行 done wait #等待上面放入后台的命令执行完毕后,在往下执行(若是后面还有要执行的命令,最好加上wait),由于命令一旦放到后台执行,这条任务就交个操做系统了,shell脚本会不等上面的执行完毕,就会继续往下执行。
扩展知识点:
咱们知道了什么是shell脚本的并发,试想一下,若是此时有1000个任务并发,就会有1000个线程产生,若是系统的资源跟不上,就会让计算机系统产生很大的压力,致使操做系统处理的速度会愈来愈慢。而此时咱们又当如何解决呢?出现这个状况时,咱们能够引入命名管道文件来处理。
命名管道处理的思路:
就至关于此时有10个开水房间,配有10把钥匙,此时有100我的要打开水,那么前10我的抢到钥匙,就先进去打开水,后面的90我的就须要等前面一我的出来后还回钥匙,在拿着钥匙进去打开水,这样就能控制100我的打开水的任务,同时不会将系统的资源一次性耗用太多,增长压力,减少处理速度。
知识点:
一、命名管道的特性
若是管道内容为空,则阻塞
管道具备读一个少一个,存一个读一个的性质,放回去的能够重复取
能够实现队列控制
二、若是管道放一段内容没有人取,则会阻塞
解决上述问题,能够经过文件描述符
文件描述符具备管道的全部特性,同时还具备一个管道不具备的特性:无限存不阻塞,无限取不阻塞,无需关注管道内容
建立方式:
一、建立命名管道mkfifo /tmp/fl
二、建立文件描述符100,并关联到管道文件exec 100<>/tmp/fl
三、调用文件描述符,向管道里存放内容,同时也表示将用完的管道内容在放回管道echo >&100
四、读取文件描述符关联管道中的内容
`read -u100``
五、关闭文件描述符的读和写bash
exec 100<&- exec 100>&-
实例演示:引用上面的网络测试案例网络
#!/bin/bash . /etc/init.d/functions cmd="ping -c 2" mkfifo /tmp/fl exec 100<>/tmp/fl rm -rf /tmp/fl for ((n=1;n<=100;n++));do echo >&100 done for ((i=1;i<=254;i++));do read -u100 { $cmd 192.168.80.$i &>/dev/null if [ $? = 0 ];then echo "192.168.80.$i is ok" else echo "192.168.80.$i is no" fi echo >&100 #将管道内容在放回去 }& done wait #echo "test compelet" exec 100<&- exec 100>&-