学习Shell脚本的多进程并发与控制
⼀、前⾔ 在⽇常数据处理过程中,很多时候⽤的都是单进程处理;如果任务较⼤的时候,这样耗时⽐较久同时也浪费资源,可将任务多进程并发处理,并合理控制其进程数,将很有效的利⽤机器资源、减少时间。经过资料查询与实践,这⾥脚本的功能就是产⽣多进程并控制其并⾏进程数量。具体多进程的好处可以参考其他资料,这⾥就不细说了。 并⾏进程数超过任务总数是没有意义的,因为实际并⾏总数会⼩于等于任务总数; ⼆、应⽤场景 ⽐如抓取⽹页数据,⽐如需要抓取100w个⽹页的数据,将其数据过滤后存⼊数据库,如果采⽤单进程或者⼿⼯操作肯定是很⿇烦耗时的,因此,采⽤这种⽅式会很好的提⾼效率。但是,如果循环处理的⼦任务耗时过短,如:只有⼀个命令等,那就没有必要控制多进程,因为那样就增加了运⾏时间,但是⼀般单个任务处理时间超过1s且任务量⽐较⼤时,我个⼈认为多进程控制还是很有必要。 其他:批量数据⽂件导⼊数据库、数据库数据批量导出为多个⽂件也可以使⽤这种⽅式; 三、使⽤说明 如果要利⽤模板脚本处理任务,那么只需要在下图红⾊处按要求添加⾃⼰的任务处理即可(后续测试实例简单地处理了⼀下模板),具体源码与注释见附件(运⾏环境Linux bash); <<;多进程并发与控制脚本-处理流程图>> 四、测试实例 1. 我⾃⼰根据模板脚本写了⼀个测试例⼦;将指定规则的⽂本信息输出到1000个⽂件中,共有10000条记录,输出后睡眠3s(⽤于测试),控制进程为1000个。主要是验证是否能够达到多进程及其控制的效果。在⾥⾯处理⽇志的时候还加⼊了⼀些⽂件描述符重定向有关的东西。 2. 源码见附件(运⾏环境Linux bash) 注:说得⽐较详细;实际操作过程中可简化代
shell最简单脚本码,实现功能! 由于⽆法附件,源码: 模板_MultiProcess.sh >>>### #简单说明: # 多进程控制利⽤读取管道⽂件fifo实现并发进程数量的控制; # 运⾏:$1 并⾏进程数 >>>### #!/bin/bash ####⽬录/⽂件变量设置>>>#### TmpFifoFile=~/tmp/$$.fifo #临时管道⽂件 >>>>>>## #防⽌异常爆发 set -eo pipefail >>#⾃定义函数区域BEGIN>> >#### #此处定义需要处理的函数逻辑[ 说明 ] # #任务逻辑 #⼀个read -u6命令执⾏⼀次,就从fd6中减去⼀个回车符,然后向下执⾏, #fd6中没有回车符的时候,就停在这了,从⽽实现了进程数量控制 #read-u6 #读取令牌 #do #( #function循环⼦任务处理函数(此处⼀般不再开⽴⼦进程处理) #当任务处理完成后,再向fd6中加上⼀个回车符,即补上了read -u6减去的那个,⼦进程>会继承⽗ #进程的⽂件描述符 #echo >&6释放令牌 #)&
#done #wait >> function deal_task() { return 0 } >##⾃定义函数区域END>## #创建并⾏进程令牌 #⽬前令牌⽤的⽂件符6 function create_token() { proc_num=$1 #令牌数 #获取当前登录⽤户最⼤可⽤进程 UserMaxUseProcNum=$(expr $(ulimit -u) - $(ps -ef|awk -F " " '{print $1}'|grep $(whoami)|wc -l)) if [ $# -ne 1 ] then echo "USAG: $0 并⾏进程数(当前⽤户可⽤${UserMaxUseProcNum},建议不超过1/3,实际最⼤进程数为所有⼦任务数)" return 1 fi #判别输⼊并⾏进程数是否符合要求) test=1 if [ ${proc_num} -gt ${UserMaxUseProcNum} ] then echo "ERROR!输
⼊进程总数${proc_num}⼤于当前⽤户可⽤进程总数${UserMaxUseProcNum}" return 1 fi #建⽴临时管道⽤于控制并发进程数 tmp_fifofile="/tmp/$$.fifo" mkfifo $tmp_fifofile exec 6<>$tmp_fifofile # 将fd6指向fifo⽂件,设置读写 rm $tmp_fifofile #清除管道⽂件 #根据传⼊的进程数量定义令牌数 for
((i=1;i<=${proc_num};i++)) do echo done >&6 return 0 } >主进程设置>>># echo "脚本运⾏--开始----
`date`-------------" ( echo "**创建令牌 begin**" #传⼊进程数量 create_token $1 ||{ echo "创建进程令牌失败" exit 1 } echo "**创建令牌 end**" echo "**任务处理 begin**" deal_task ||{ echo "任务处理失败!" exit 1 } echo "**任务处理 end**" )& #等待任务处理完毕 wait exec 6<&- #释放⽂件描述符 echo "脚本运⾏--结束----`date`-------------" 实例MultiProcess_CreateFile.sh >>>### #简单说明: # 多进程控制利⽤读取管道⽂件fifo实现并发进程数量的控制; # 运⾏:$1 并⾏进程数 # 功能: # 测试⽣成10000条记录,共1000个⽂件,最⼤并⾏进程数为1000 >>>### #!/bin/bash ####⽬录/⽂件变量设置>>>#### TmpFifoFile=~/tmp/$$.fifo #临时管道⽂件 OutDataPath=./data #输出⽂件路径 by yuanwm OutLogPath=./log #输出⽇志⽂件 by yuanwm errlogname=$$.errlog #错误⽇志⽂件 by yuanwm runlogname=$$.runlog #运⾏⽇志⽂件 by yuanwm
>>>>>>## #防⽌异常爆发 set -eo pipefail >>#⾃定义函数区域
BEGIN>> >#### #此处定义需要处理的函数逻辑[ 说明 ] # #任务逻辑 #⼀个read -u6命令执⾏⼀次,就从fd6中减去⼀个回车符,然后向下执⾏, #fd6中没有回车符的时候,就停在这了,从⽽实现了进程数量控制 #read-u6 #读取令牌 #do #( #function循环⼦任务处理函数(此处⼀般不再开⽴⼦进程处理) #当任务处理完成后,再向fd6中加上⼀个回车符,即补上了read -u6减去的那个,⼦进程>会继承⽗ #进程的⽂件描述符 #echo >&6释放令牌 #)& #done #wait >> function deal_task() { #define by yuanwm #测试⽣成10000条记录,共1000个⽂件 for((i=0;i<10000;i++)) do read -u6 ( echo "处理任务 ${i}" echo "编号$i|测试企业名称$i|测试联系⼈$i|测试联系⼈号码$i" >> ${OutDataPath}/test_data_`expr $i % 1000 `.txt sleep 3 echo >&6 )& done wait return 0 } >##⾃定义函数区域END>## #创建并⾏进程令牌 #⽬前令牌⽤的⽂件符6 function create_token() {
proc_num=$1 #令牌数 #获取当前登录⽤户最⼤可⽤进程 UserMaxUseProcNum=$(expr $(ulimit -u) - $(ps -ef|awk -F " " '{print $1}'|grep $(whoami)|wc -l)) if [ $# -ne 1 ] then echo "USAG: $0 并⾏进程数(当前⽤户可⽤${UserMaxUseProcNum},建议不超过
1/3,实际最⼤进程数为所有⼦任务数)" return 1 fi #判别输⼊并⾏进程数是否符合要求) if [ ${proc_num} -gt ${UserMaxUseProcNum} ] then echo "ERROR!输⼊进程总数${proc_num}⼤于当前⽤户可⽤进程总数${UserMaxUseProcNum}" return 1 fi #建⽴临时管道⽤于控制并发进程数 tmp_fifofile="/tmp/$$.fifo" mkfifo $tmp_fifofile exec 6<>$tmp_fifofile # 将fd6指向fifo⽂件,设置读写 r
m $tmp_fifofile #清除管道⽂件 #根据传⼊的进程数量定义令牌数 for ((i=1;i<=${proc_num};i++)) do echo done>&6 return 0 } >主进程设置>>># echo "脚本运⾏--开始----`date`-------------" #⽬录创建 mkdir -p ${OutDataPath} mkdir -p ${OutLogPath} #⽇志重定向 exec 5<&1 #标准输出保存 exec 7<&2 #标准错误保存 exec 1>>${OutLogPath}/${runlogname} exec 2>>${OutLogPath}/${errlogname} ( echo "**创建令牌 begin**" #传⼊进程数量 create_token $1 ||{ echo "创建进程令牌失败" exit 1 } echo "**创建令牌 end**" echo "**任务处理 begin**" deal_task ||{ echo "任务处理失败!" exit 1 } echo "**任务处理 end**" )& #等待任务处理完毕 wait exec 1<&5 #标准输出还原 exec 6<&- #释放⽂件描述符 exec 5<&- #释放⽂件描述符 exec 7<&- #释放⽂件描述符echo "脚本运⾏--结束----`date`-------------"
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
TCL脚本语言详解
« 上一篇
推荐文章
热门文章
-
随机森林算法的改进方法
2024-10-02 -
基于随机森林算法的风险预警模型研究
2024-10-02 -
Python中的随机森林算法详解
2024-10-02 -
随机森林发展历史
2024-10-02 -
如何使用随机森林进行时间序列数据模式识别(八)
2024-10-02 -
随机森林回归模型原理
2024-10-02 -
如何使用随机森林进行时间序列数据模式识别(六)
2024-10-02 -
如何使用随机森林进行时间序列数据预测(四)
2024-10-02 -
如何使用随机森林进行异常检测(六)
2024-10-02 -
随机森林算法和grandientboosting算法 -回复
2024-10-02 -
随机森林方法总结全面
2024-10-02 -
随机森林算法原理和步骤
2024-10-02 -
随机森林的原理
2024-10-02 -
随机森林 重要性
2024-10-02 -
随机森林算法
2024-10-02 -
机器学习中随机森林的原理
2024-10-02 -
随机森林算法原理
2024-10-02 -
使用计算机视觉技术进行动物识别的技巧
2024-10-02 -
基于crf命名实体识别实验总结
2024-10-02 -
transformer预测模型训练方法
2024-10-02
最新文章
-
随机森林算法介绍及R语言实现
2024-10-02 -
基于随机森林优化的神经网络算法在冬小麦产量预测中的应用研究_百度文 ...
2024-10-02 -
基于正则化贪心森林算法的情感分析方法研究
2024-10-02 -
随机森林算法和grandientboosting算法
2024-10-02 -
基于随机森林的图像分类算法研究
2024-10-02 -
随机森林结合直接正交信号校正的模型传递方法
2024-10-02
发表评论