zoukankan      html  css  js  c++  java
  • shell——wait与多进程并发

    在脚本里用&后台打开多个子进程,用wait命令可以使这些子进程并行执行。

    例1:

    fun1(){
    while true
    do
    echo 1
    sleep 1
    done
    }
    
    fun2(){
    while true
    do
    echo 2
    sleep 1
    done
    }
    
    fun1 &
    fun2 &
    wait

    例2:

    #!/bin/bash
    for ((i=0;i<5;i++))
    do
    sleep 3;echo a
    done
    
    #运行需要15秒。
    
    
    #!/bin/bash
    for ((i=0;i<5;i++))
    do
    {
    sleep 3;echo a
    } &
    done
    wait
    
    #打开5个子进程并行,运行只需要3秒。

    例3:

    用管道fifo文件来处理并发,本例转自https://my.oschina.net/sanpeterguo/blog/133304

    相关知识:

    read -u的介绍:https://www.cnblogs.com/maxgongzuo/p/6414474.html

    mkfifo管道:https://www.cnblogs.com/maxgongzuo/p/6414466.html

    eval和exec:https://www.cnblogs.com/maxgongzuo/p/6414453.html

    #!/bin/bash
    #author :  peterguo@tencent.com
    #date   :  2013.05.24
    
    
    #sub process do something
    function a_sub_process { 
        echo "processing in pid [$$]"
        sleep 1
    }
    
    
    #创建一个fifo文件
    FIFO_FILE=/tmp/$.fifo
    mkfifo $FIFO_FILE
    
    
    #关联fifo文件和fd6
    exec 6<>$FIFO_FILE      # 将fd6指向fifo类型
    rm $FIFO_FILE
    
    
    #最大进程数
    PROCESS_NUM=4
    
    
    #向fd6中输入$PROCESS_NUM个回车
    for ((idx=0;idx<$PROCESS_NUM;idx++));
    do
        echo
    done >&6 
    
    
    #处理业务,可以使用while
    for ((idx=0;idx<20;idx++));
    do
        read -u6  #read -u6命令执行一次,相当于尝试从fd6中获取一行,如果获取不到,则阻塞
        #获取到了一行后,fd6就少了一行了,开始处理子进程,子进程放在后台执行
        {
          a_sub_process && { 
             echo "sub_process is finished"
          } || {
             echo "sub error"
          }
          #完成后再补充一个回车到fd6中,释放一个锁
          echo >&6 # 当进程结束以后,再向fd6中加上一个回车符,即补上了read -u6减去的那个
        } &
    done
    
    
    #关闭fd6
    exec 6>&- 

    关于例3,在实际应用中,进行了一些更改。 

    #!/bin/bash
    ####### env ########
    first_taskid=1
    PROCESS_NUM=3
    
    
    ####### func ########
    function do_process {
        local taskid=$2
        [ $taskid -eq 1 ] && local gpuid=0
        [ $taskid -eq 2 ] && local gpuid=1
        [ $taskid -eq 3 ] && local gpuid=3
        sh tran.sh $1 $taskid $gpuid &
        hang $1 $taskid $gpuid
        # wait
        # echo >&6
    }
    
    function hang {
        while true
        do
        sleep 1800
        ps -ef|grep "sh tran.sh $1 $2 $3" |grep -v grep
        [ $? -eq 0 ] && continue || break
        done
        echo >&6
    }
    
    
    ######## fifo ########
    FIFO_FILE=$(mktemp) # 建立一个随机的不重名的临时文件
    rm $FIFO_FILE
    mkfifo $FIFO_FILE
    trap "rm $FIFO_FILE" 15
    trap "rm $FIFO_FILE" 9
    exec 6<>$FIFO_FILE
    
    for ((idx=0;idx<$PROCESS_NUM;idx++));
    do
        echo
    done >&6 
    
    
    ######## main ##########
    for i in `cat tmp.txt`
    do
        read -u6
        taskid=$(( $first_taskid % $PROCESS_NUM ))
        [ $taskid -eq 0 ] && taskid=$PROCESS_NUM
        do_process $i $taskid &
        ((first_taskid++))
    done
    
    
    ######## end #########
    exec 6>&-   # 关闭fd6
    rm $FIFO_FILE
  • 相关阅读:
    Extjs 4.x 得到form CheckBox的值
    你是工具综合症和资料收集狂患者吗?(转)
    计算机网络第五版(谢希仁)读书笔记(三)
    《别做正常的傻瓜》 读书笔记
    2013年11月27日,开始写专业的博客。
    web输入框的测试
    linux 文件操作相关函数
    Samba的安装
    linux df命令参数详解
    linux arp 命令常用参数详解
  • 原文地址:https://www.cnblogs.com/maxgongzuo/p/6414376.html
Copyright © 2011-2022 走看看