最新消息:

bash/shell并发

未分类 admin 3061浏览 0评论

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

您必须 登录 才能发表评论!