shell后台并发执行的最佳实践

一、shell如何在后台执行
1.nohup命令
通常我们都是远程登录linux终端,而当我们退出终端时在之前终端运行的程序都会终止,有时候先想要退出终端也要程序继续执行这时nohup就登场了。 nohup命令 可以将程序以忽略挂起信号的方式运行起来,被运行的程序的输出信息将不会显示到终端。
nohup command > myout. file 2>&1 &
2.&后台执行
在命令后面加 & 可以让程序在后台执行
command &
3.Ctrl + z
当一个程序正在执行并且占用当前终端时我们同时按下 Ctrl + z ,这样就会把正在执行的前台程序放到后台挂起。
二、常规并发执行
1.正常执行
#!/bin/bash
Njob=15    #任务总数
for ((i=0; i<$Njob; i++)); do
{
          echo  "progress $i is sleeping for 3 seconds zzz…"
          sleep  3
}
done
echo -e "time-consuming: $SECONDS    seconds"    #显示脚本执行耗时
shell后台并发执行的最佳实践_第1张图片
2.并发后台执行
#!/bin/bash
Njob=15
for ((i=0; i<$Njob; i++)); do
          echo  "progress $i is sleeping for 3 seconds zzz…"
          sleep  3 &       #循环内容放到后台执行
done
wait      #等待循环结束再执行wait后面的内容
echo -e "time-consuming: $SECONDS    seconds"    #显示脚本执行耗时
shell后台并发执行的最佳实践_第2张图片
以这种方式进行后台执行执行的效率较高、速度快,但是当并发数过多时就有可能会造成系统奔溃。
3.以队列方式并发后台执行

就上面的并发执行的缺点,我们可以分批并行的方式并发执行。每批的执行进程数固定并不会引起系统奔溃。

#!/bin/bash                                                                                    
NQ=3                                                                                                           
num=5                                                                                                        
for ((i=0; i<$NQ; i++)); do                                                                              
     for ((j=0; j<$num; j++)); do                                                                    
         echo  "progress $i is sleeping for 3 seconds zzz…"                
        sleep 3 &               
     done                
     wait               
 done             
#等待循环结束再执行wait后面的内容               
echo -e "time-consuming: $SECONDS    seconds"    #显示脚本执行耗时  

shell后台并发执行的最佳实践_第3张图片

三、最佳实践
以队列的形式并发执行固然很好,每次并发的进程是可控的,可以提高效率还能防止系统奔溃。但是存在一个问题就是每一批的并发进程的执行时间是由这些进程里面执行最慢的决定,先前执行完的进程要等待没有执行完的进程。下面介绍并发执行的最佳实践
able File  45 lines (37 sloc)  696 Bytes
#!/bin/bash
# 并发运行的最佳实践

# 总进程数
Sp=15
# 并发数,并发数过大可能造成系统崩溃
Qp=5
# 存放进程的队列
Qarr=();
# 运行进程数
run=0
# 将进程的添加到队列里的函数
function push() {
	Qarr=(${Qarr[@]} $1)
	run=${#Qarr[@]}
}
# 检测队列里的进程是否运行完毕
function check() {
	oldQ=(${Qarr[@]})
	Qarr=()
	for p in "${oldQ[@]}";do
		if [[ -d "/proc/$p" ]];then
			Qarr=(${Qarr[@]} $p)	
		fi
	done
	run=${#Qarr[@]}
}

# main
for((i=0; i<$Sp; i++));do
	echo "running $i " 
	sleep 3 &
	push $!
	while [[ $run -gt $Qp ]];do
		check
		sleep 0.1
	done
done
echo -e "time-consuming: $SECONDS   seconds"    #显示脚本执行耗时
shell后台并发执行的最佳实践_第4张图片
大家可以看见同样是可控并发数量,总数量同为15个进程,每次都并发执行5个进程,效率提高了进30%。


本篇文章主要参考了:微信公众号上的一篇文章《Shell脚本实现并发多进程》,但是具体链接我忘记了。

你可能感兴趣的:(shell,linux,非专业linux运维工程师专栏)