Windows Ubuntu wordpress java 微软 linux HTML5 centos nginx 开源 Python php apache Firefox linux命令 shell google Android 程序员 mysql

bash/shell并发

又一篇写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

延伸阅读

评论