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
- 点赞
- 收藏
- 关注作者
作者其他文章
Fitz2017/11/28 07:03:351楼编辑删除举报
Fe2017/11/29 04:50:252楼编辑删除举报