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秒

 

 

  

posted @ 2021-07-21 19:21  Liuyim  阅读(1104)  评论(0编辑  收藏  举报