shell实现并发控制

需求: 并发检测100台web服务器状态(或者并发为100台web服务器分发文件等)如何用shell实现?

方案一:(单进程)

思路:一个for循环100次顺序执行100次任务。

#!/bin/bash
start_time=`date +%s` #定义脚本运行的开始时间
 
for ((i=1;i<=100;i++))
do

sleep 1 #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替) echo 'success'$i; done stop_time=`date +%s` #定义脚本运行的结束时间 echo "TIME:`expr $stop_time - $start_time`"

执行结果

 

代码解析及问题

 一个for循环1000次相当于需要处理1000个任务,循环sleep 1代表运行一个命令需要的时间,用 success$i 来标示每条任务。
 这样写的问题是,1000条命令都是顺序执行的,完成是阻塞时的运行,假如每条命令的运行时间是1秒的话,那么1000条命令的运行时间是1000秒,效率相当低,
而要求是并发检测1000台web的存活,如果采用这种顺序的方式,那么假如我有1000台web,这时候第900台机器挂掉了,检测到这台机器状态所需要的时间就是900s
! 所以,问题关键集中在一点:如何并发。

 

 方案二:全并发

思路:一个for循环1000次,循环体里面的每个任务放入后台运行(在命令后面加&符号代表后台运行)。

#!bin/bash
start=`date +%s` #定义脚本运行的开始时间
 
for ((i=1;i<=100;i++))
do
{
        sleep 1  #sleep 1用来模仿执行一条命令需要花费的时间(可以用真实命令来代替)
        echo 'success'$i; 
}&               #用{}把循环体括起来,后加一个&符号,代表每次循环都把命令放入后台运行
                 #一旦放入后台,就意味着{}里面的命令交给操作系统的一个线程处理了
                 #循环了100次,就有100个&把任务放入后台,操作系统会并发1000个线程来处理
                 #这些任务         
done    
wait             #wait命令的意思是,等待(wait命令)上面的命令(放入后台的)都执行完毕了再
                 #往下执行。
                 #在这里写wait是因为,一条命令一旦被放入后台后,这条任务就交给了操作系统
                 #shell脚本会继续往下运行(也就是说:shell脚本里面一旦碰到&符号就只管把它
                 #前面的命令放入后台就算完成任务了,具体执行交给操作系统去做,脚本会继续
                 #往下执行),所以要在这个位置加上wait命令,等待操作系统执行完所有后台命令
end=`date +%s`  #定义脚本运行的结束时间
 
echo "TIME:`expr $end - $start`"

执行结果

 

 代码分析以及问题

 shell实现并发,就是把循环体的命令用&符号放入后台运行,100个任务就会并发100个线程,运行时间1s,比起方案一的100s,已经非常快了。
 可以看出输出结果success4…success3完全都是无序的,因为大家都是后台运行的,这个时候就是CPU随机运行了,所以并没有什么顺序。
 这样写确实可以实现并发,然后,大家可以想象一下,1000个任务就要并发1000个线程,这样对操作系统造成的压力非常大,
它会随着并发任务数的增多,操作系统处理速度会慢甚至出现其他不稳定因素,就好比你在对nginx调优后,你认为你的nginx理论上最大可以支持1w并发,实际上呢,你
的系统会随着高并发压力会不断攀升,处理速度会越来越慢。

 

并发数量控制

参考:https://blog.csdn.net/imliuqun123/article/details/107038747 

 

posted @ 2022-11-15 15:03  羊脂玉净瓶  阅读(367)  评论(0)    收藏  举报