Shell脚本中的多任务并发执行
正常情况下,Shell脚本中的命令是串行执行的,当一条命令执行完才会执行接下来的命令。比如下面这段代码:
#!/bin/bash for i in {1..10};do echo $i done echo "END" 执行结果: 1 2 3 4 5 6 7 8 9 10 END 可以看到,循环体中的“echo $i”命令是串行执行的。但是如果所执行的命令耗时比较长,这就会导致整个程序的执行时间非常长,甚至可能导致程序执行时卡在那里,长时间失去响应。 #!/bin/bash for i in {1..254};do ip="192.168.80.$i" ping -c 2 $ip &> /dev/null && echo $ip is up done 这里对脚本中使用的ping命令稍作说明。Linux中的ping命令在执行后会连续不断地发包,因而脚本中的ping命令使用了“-c”选项,指定只发2次包,如果能收到响应,就认为目标主机在线。 [[email?protected] ~]# bash ping.sh 192.168.80.1 is up 192.168.80.2 is up ^C ^Z [1]+ 已停止 bash ping.sh [[email?protected] ~]# jobs -l #查看后台工作任务 [1]+ 101100 停止 bash ping.sh [[email?protected] ~]# kill -9 101100 #强制结束进程 [[email?protected] ~]# [1]+ 已杀死 bash ping.sh 实际上在这个脚本中所循环执行的ping命令之间并没有依赖关系,也就是说不必非要等到“ping 192.168.80.1”结束之后才能接着执行“ping 192.168.80.2”,所有的这些ping命令完全可以并发执行。 #!/bin/bash for i in {1..10};do echo $i & done echo "END" 执行结果: [[email?protected] ~]# bash test.sh END [[email?protected] ~]# 1 2 3 6 7 4 8 9 10 5 可以看到,在并发执行时不能保证命令的执行顺序,而且本应在整个循环执行结束之后再执行的echo "END"命令,却在程序一开始就被执行了。所以在并发执行时,我们通常都需要保证在循环体中的所有命令都执行完后再向后执行接下来的命令,这时就可以使用 wait命令来实现。在Shell中使用wait命令,相当于其它高级语言里的多线程同步。 #!/bin/bash for i in {1..10};do echo $i & done wait echo "END" 这样执行结果就正常了: [[email?protected] ~]# bash test3.sh 6 7 2 3 4 8 9 10 5 1 END 了解了程序并发执行的原理之后,我们对ping脚本也同样进行改进: #!/bin/bash for i in {1..254};do ip="192.168.80.$i" ping -c 2 $ip &> /dev/null && echo $ip is up & done wait 此时脚本的执行速度将大大提高: [[email?protected] ~]# bash ping.sh 192.168.80.10 is up 192.168.80.20 is up 192.168.80.2 is up 192.168.80.1 is up 192.168.80.135 is up 因而当要循环执行的命令之间没有依赖关系时,完全可以采用并发执行的方式,这样可以大幅提高代码执行效率。当然并发执行也有缺陷,就是当需要并行执行的命令数量特别多,特别是所执行的命令占用的系统资源非常多时,可能会将整个系统的资源全部耗尽,影响其它程序的运行,因而还可以借助其它技术来限制并发执行的进程数量,由于比较复杂,本文就不做介绍了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |