首页 > 代码库 > 关于bash如何进行并发执行!

关于bash如何进行并发执行!

  通常我们用脚本对一批机器做操作的时候,我们会用如下的代码片段:

                for i in `cat ip.txt`; do

        # To do something...

        echo $?

                done

        但是这样的模版有个问题,在机器数量比较少的时候,还能取得比较满意的效果。但是如果试想一下!当ip.txt中的主机数量上百,而To do something又是一个比较耗时的操作的时候,这样的脚本运行一次可能需要的时间就不是一小会了。虽然我们可以盯着屏幕,看着自己写的脚本平稳地运行,心情也会很好。但是这样长时间的等待毕竟是一件不能令人愉快的事情。这个时候我们就在想,能不能对脚本做并发呢?让系统对每一个To do something都同时运行呢。这样在一定范围数量内的运行时间就非常令人可观了(为什么是一定范围数量呢?后面会解释)!其实我们可以用这样的代码片段来代替上面的:

                for i in `cat ip.txt`; do

        {

            # To do something

            echo $?

        } &

                done

        如此一来,脚本的运行就会针对每一次循环开启一个子shell进行运算了。时间上也会节省很多。下面是一个ping的例子。

        假如我有10台主机,ip地址都写在ip.txt中,然后我要对这些主机每一台进行:ping -c 5 <ip_address>,那么我可以这么写。

                for i in `cat ip.txt`; do

        {

            ping -c 5 $i

            echo $?

        } &

                done

        如果我还用原来的方式进行ping的话,可能需要用到将近50秒左右的时间,但是如果放在并发里面的话时间就会缩短到5秒左右。这样看来是比较理想的情况了,但是我们在继续想一下(呵呵,运维的工作的复杂度是和机器数量成正比的^_^!),如果此时有500台机器要ping怎么办?我们还用上面的并发代码片段就会有问题了。我猜想运行的时候系统可能会变的很慢,因为系统要开500个子shell来完成这些工作。所以下面我们需要控制同时并发的数量,不能让系统同时运行太多的子shell。网上看到有一些用管道做的,但是感觉太复杂(呵呵,主要是自己没看懂),其实我们可以这样考虑,不妨把上面的并发代码段看成是一个类似进程池的东西,我们把:for i in `cat ip.txt`部分改造成为一个固定次数的循环,然后增加一个数组,每次往这个数组中放置好ip,然后用循环处理,看起来应该是这个样子:

                a=(ip1 ip2 ip3 ip4 ip5)

                for ((i=0; i<5; i++)); do

        {

            ping -c 5 ${a[i]}

            echo $?

        } &

                done

        然后每次读取ip.txt中的5个ip后再调用这个代码片段。这样每次就控制在5个进程了,应该不会导致系统卡住或者很慢。

                                                                                           

本文出自 “Linux Oracle MariaDB” 博客,请务必保留此出处http://wangergui.blog.51cto.com/8504247/1926853

关于bash如何进行并发执行!