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秒

浙公网安备 33010602011771号