Multitasking Shell script concurrent execution

Under normal circumstances, Shell script command is executed serially, when a command finishes before executing the next command. For example, the following code:

 #!/bin/bash
for i in {1..10};do
echo $i 
done
echo "END"

Results of the:

1
2
3
4
5
6
7
8
9
10
END

It can be seen in the loop "echo $ i" command is executed serially. But if the command execution takes longer, which will lead to the execution time of the whole process is very long, and may even lead to stuck there during program execution, prolonged loss of response.
For example, we need to complete such a task: to write a script that scans 192.168.80.0/24 network, which currently hosts online, can ping believes online.
To accomplish this task, to write the script is not complicated, the following code is written:

 #!/bin/bash
for i in {1..254};do
        ip="192.168.80.$i"
        ping -c 2 $ip &> /dev/null && echo $ip is up 
done

Here a brief description of the ping command used in the script. Linux in the ping command will continuously contract after execution, so the script ping command uses the "-c" option, specify only made twice a package, if a response is received, it is considered the target host online.
This script logically and there is no problem, but after performing due to turn 254 ping the IP address of the network, takes very long, but this time the script can not be forced to use Ctrl + C to terminate, can only use the Ctrl + Z into the background, and then use the kill command terminates the process.

 [root@localhost ~]# bash ping.sh
192.168.80.1 is up
192.168.80.2 is up
^C
^Z
[1]+  已停止               bash ping.sh
[root@localhost ~]# jobs -l                             #查看后台工作任务
[1]+ 101100 停止                  bash ping.sh
[root@localhost ~]# kill -9 101100                      #强制结束进程
[root@localhost ~]# 
[1]+  已杀死               bash ping.sh

Virtually no dependencies between the ping command in the script in the execution of the loop, that do not have to wait until the "ping 192.168.80.1" to the end and then execute "ping 192.168.80.2", all of these ping command entirely you can execute concurrently.
If you are using Python, you can achieve concurrent execution of commands by means of multi-threading technology, and Shell does not support multi-threaded, multi-process which can only by way of. The specific method is very simple, that is, after the command to be executed concurrently with "&", it was taken into the background, so that you can execute a command after completion, without waiting for the end of its execution, immediately turn to the next execution a command.
We were still before the code as an example, add "&" after the body of the loop echo command:

 #!/bin/bash
for i in {1..10};do
echo $i &
done
echo "END"

Results of the:

 [root@localhost ~]# bash test.sh
END
[root@localhost ~]# 1
2
3
6
7
4
8
9
10
5

It can be seen in the concurrent execution of the command execution order is not guaranteed, and echo should be performed again after the end of the implementation of the entire cycle "END" command, it is executed at the beginning of the program. So when concurrent execution, we often need to ensure that all commands in the body of the loop are executed after the next command after again, then you can use the wait command. Use the wait command in the Shell, equivalent to other high-level language in the multi-thread synchronization.
Next, the code modifications, additions wait command:

 #!/bin/bash
for i in {1..10};do
echo $i &
done
wait
echo "END"

In this way the results to normal:

 [root@localhost ~]# bash test3.sh
6
7
2
3
4
8
9
10
5
1
END

After understanding the principle of concurrent execution of the program, we also improve ping script:

 #!/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

At this point the script execution speed will be greatly enhanced:

 [root@localhost ~]# 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

Thus when there is no dependency between the command to be executed in a loop, can by way of concurrent execution, which can significantly improve the efficiency of the code. Of course, concurrent execution is also flawed, that is, when a particularly large number of parallel execution of commands need, especially the executed command system resources very long time, might deplete all the resources of the entire system, affecting the operation of other programs, which can also be With other techniques to limit the number of concurrent execution of the process, due to the more complex, this article not be introduced.

Guess you like

Origin blog.51cto.com/yttitan/2409618