Shell脚本模拟多线程
【摘要】 背景: 最近经常用Shell处理一些循环任务,在一个循环中并不需要太多的cpu资源,但是需要占用一定时间。shell是一个典型面向过程脚本,这样逐个执行循环需要消耗大量时间。比如在80台主机情况下,我的批量后台操作一个“ifconfig”执行就需要用约5分钟执行完;批量nmap扫描tcp端口需要大约3分钟,而默认情况下扫描udp竟然需要大概50天!思路: Shell中可
背景:
最近经常用Shell处理一些循环任务,在一个循环中并不需要太多的cpu资源,但是需要占用一定时间。shell是一个典型面向过程脚本,这样逐个执行循环需要消耗大量时间。比如在80台主机情况下,我的批量后台操作一个“ifconfig”执行就需要用约5分钟执行完;批量nmap扫描tcp端口需要大约3分钟,而默认情况下扫描udp竟然需要大概50天!
思路:
Shell中可以使用“&”将某个子进程放到后台执行,我再使用fifo类型文件计数来控制放到后台执行的子进程的数量,最后用wait等全部子进程执行完,继续往下走,借此原理可以曲线实现多进程并发处理任务的目的。
示例:
以一个非常简单的例子来说明多进程对执行效率提升的帮助:循环0-99整数,与10取余,并按结果sleep,目的是让每个进程执行的时间有较大差异,方便看出子进程的执行情况
传统写法:
#!/bin/bash fn_num () #用于测试的函数,传进来一个整数与10取余,并按照结果sleep { #目的是让每个进程执行的时间有较大差异,方便看出子进程情况 a=$1 b=$(( $a % 10 )) echo "--->$a" #标记子进程开始执行 sleep $b echo "<------------------$a" #标记子进程执行结束 } for (( i=0;i < 100;i++ )) do { fn_num $i } done echo "over"
使用“多进程”写法
#!/bin/bash THREAD_NUM=10 #定义进程数量 if [[ -a tmp ]];then #防止计数文件存在引起冲突 rm tmp #若存在先删除 fi mkfifo tmp #创建fifo型文件用于计数 exec 9<>tmp for (( i=0;i<$THREAD_NUM;i++ )) #向fd9文件中写回车,有多少个进程就写多少个 do echo -ne "\n" 1>&9 done fn_num () #用于测试的函数,传进来一个整数与10取余,并按照结果sleep { #目的是让每个进程执行的时间有较大差异,方便看出子进程情况 a=$1 b=$(( $a % 10 )) echo "--->$a" #标记子进程开始执行 sleep $b echo "<------------------$a" #标记子进程执行结束 } for (( i=0;i < 100;i++ )) do { read -u 9 #read一次,就减去fd9中一个回车 { #当fd9中没有回车符时,脚本就会停住,达到控制进程数量的目的 fn_num $i echo -ne "\n" 1>&9 #某个子进程执行结束,向fd9追加一个回车符,补充循环开始减去的那个 }& } done wait #等待所有后台子进程结束 echo "over" rm tmp
看下执行过程:
单进程:
每次循环只按照顺序读取一个数字,执行完毕再读取下一个,直至结束,总共耗时7m31s
linux-100:/home/admin/tmp # time sh test.sh --->0 <------------------0 --->1 <------------------1 --->2 <------------------2 --->3 <------------------3 --->4 <------------------4 --->5 <------------------5 …………………… <------------------96 --->97 <------------------97 --->98 <------------------98 --->99 <------------------99 over real 7m30.990s user 0m0.012s sys 0m0.108s
多进程:
一次读入十个整数,并进入后台同时执行,执行完的返回结果结束子进程,再读入一个数;最后所有子进程执行完毕,退出循环,总共耗时50s
linux-100:/home/admin/tmp # time sh test.sh --->0 --->1 --->2 --->4 --->3 --->6 --->8 --->9 <------------------0 --->5 --->7 --->10 <------------------10 --->11 <------------------1 --->12 <------------------11 --->13 <------------------2 --->14 <------------------12 <------------------3 --->15 --->16 <------------------4 ………………………… <------------------86 <------------------79 --->99 <------------------94 <------------------87 <------------------88 <------------------95 <------------------89 <------------------96 <------------------97 <------------------98 <------------------99 over real 0m50.124s user 0m0.008s sys 0m0.180s
通过以上对比发现,单进程需要451秒的任务,在10个进程并行执行只需要50s;若增大进程数,所需时间会更短。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)