又一篇写shell多进程的blog,之前整理过一篇,现在整理的,算是将“常见事务”封装一下,以便可以随时拿来使用。
最常见的“多进程”需求,应该就是多“worker”模型(多消费者模型)了,即一个(或多个)进程负责提供数据,多个进程(worker)负责处理(消费)数据。
在shell中启动多个进程的要点,是要用“jobs”控制符 ‘&’启动任务,即将任务放到后台运行。
shell的多进程难点在于如何控制多进程有几个。
解决这个问题,需要巧用管道文件。如下例
batch_job() { # 花开的地方 # http://www.bsmdap.com/ # 定义并发数量 local num=$1 # 定义“数据”来源 local list_file=$2 # 定义“worker”,传递给“worker”的“位置参数”是数据文件list_file的“行” shift 2 local action=$@ # 建立管道文件,为了不受“外界”干扰,将文件打开,将文件inode信息删除(删除文件) local pipe=`mktemp -u` mkfifo $pipe # 将文件$pipe绑定到文件句柄6上(打开) exec 6<> $pipe rm -f "$pipe" # 假如并发数大于数据文件行数,即会出错,需要提前处理 local line=`wc -l $list_file|awk '{print $1}'` if [ "$num" -lt "$line" ] ; then : else num=$line fi local i for((i=0;i<num ;i++)) ; do echo done >&6 while read i ; do read -u 6 ( $action $i; echo >&6 ) & done < $list_file # 为了不让主进程在读完list_file后就退出(这时很有可能还有$num个后台任务在运行) # 此处调用wait等待 wait # 关闭文件句柄6 exec 6>&- } #下面这个</num>是wp(或者插件自动生成的,去不掉)
假定我有很多TCP服务,需要检测端口是不是活的,可以先整理一个数据文件vip_list,内容如下:
a.a.a.a 80 b.b.b.b 31 c.c.c.c 100
再定义一个action:
local_ping() { set $@ local ip=$1 local port=$2 if nc -w2 -z -t $ip $port &>/dev/null ; then echo "$ip:$port success" else echo "$ip:$port failure" fi }
然后这样调用
batch_job 10 vip_list local_ping
转载请注明:爱开源 » bash/shell并发