shell脚本多线程执行
为了更好的说明问题,我们结合例子讲解
需求:输出数字1-10,间隔为1秒
单进程实现:
vim test.sh #!/bin/bash starttime=`date +'%Y-%m-%d %H:%M:%S'` for i in `seq 10`;do echo $i sleep 1 done endtime=`date +'%Y-%m-%d %H:%M:%S'` start_seconds=$(date --date="$starttime" +%s); end_seconds=$(date --date="$endtime" +%s); echo "本次运行时间: "$((end_seconds-start_seconds))"s"
输出结果:
[root@lym ~]# sh test.sh 1 2 3 4 5 6 7 8 9 10 本次运行时间: 10s
脚本运行时间为10秒
多进程实现
改成多进程实现非常简单,只需要在do后面的大括号加 & 符号,在done后面加一个wait,表示父进程等待子进程退出后再退出
vim test.sh #!/bin/bash starttime=`date +'%Y-%m-%d %H:%M:%S'` for i in `seq 10`;do { echo $i sleep 1 }& done wait endtime=`date +'%Y-%m-%d %H:%M:%S'` start_seconds=$(date --date="$starttime" +%s); end_seconds=$(date --date="$endtime" +%s); echo "本次运行时间: "$((end_seconds-start_seconds))"s"
输出结果:
[root@lym ~]# sh test.sh 6 7 2 3 4 8 9 10 1 5 本次运行时间: 1s
本次执行时间为1秒,但是顺序会打乱以及有个问题是进程会一下子非常多,几百上千,超过系统限制报错,下面我们就加上进程数控制。
多进程实现并控制进程数量
#!/bin/bash starttime=`date +'%Y-%m-%d %H:%M:%S'` #允许的进程数 THREAD_NUM=3 #定义描述符为9的管道 mkfifo tmp exec 9<>tmp #预先写入指定数量的换行符,一个换行符代表一个进程 for ((i=0;i<$THREAD_NUM;i++)) do echo -ne "\n" 1>&9 done for i in `seq 10`;do #进程控制 read -u 9 { echo $i sleep 1 echo -ne "\n" 1>&9 }& done wait rm tmp endtime=`date +'%Y-%m-%d %H:%M:%S'` start_seconds=$(date --date="$starttime" +%s); end_seconds=$(date --date="$endtime" +%s); echo "本次运行时间: "$((end_seconds-start_seconds))"s"
上面的代码就可以保证子进程在指定数量了,其进程控制原理是通过管道实现的,当管道无内容可读时就不会执行
而且每个进程执行完成后都会向管道写入一个换行符,从而保证进程数是指定的。
输出信息:
[root@localhost ~]# sh test.sh 1 3 2 4 5 6 7 8 9 10 本次运行时间: 4s
可以看到此次控制了每次开启3个进程,所以执行时间为4秒