zoukankan      html  css  js  c++  java
  • shell多线程之进程间通信(2)

    工作中往往遇到这种情况,有许多任务,依次执行比较浪费时间,由于任务之间有依赖关系,简单的并发执行又不行。

    就如同下面这种情况,任务new和dvidUser是可以并发执行的,fact任务依赖于new任务,fact执行完之后last和stat才能执行;

    dvidUser执行完之后dvid和User两个任务才能执行。

     

    针对这种情况,我考虑了操作系统中的信号量机制,通过借助linux中的文件描述符(以下称pipe)来实现这几个任务的并发。

    当new执行完之后,向pipe-7中写入自己当前执行的ID(在程序中用$i标识,递增的),然后ID自增,继续执行;

    与此同时,fact任务不断从pipe-7中读取,我们称之为$j,然后和自己的任务ID进行比较,会有几种情况:

    1.没有读到$j,说明相同ID的前置new任务尚未执行,则fact阻塞;

    2.读到$j,$j>ID,fact执行,fact执行完之后将自己的ID同时写入pipe-8和pipe-9),以通知它的后置任务last和stat.

    其他的逻辑基本相同。代码如下:

    init_pipe.sh

    # 初始化file descriptor
    init_pipe(){
    [ -e /tmp/fd1001 ] || mkfifo /tmp/fd1001
    exec 1001<>/tmp/fd1001
    rm -rf /tmp/fd1001
    
    [ -e /tmp/fd1002 ] || mkfifo /tmp/fd1002
    exec 1002<>/tmp/fd1002
    rm -rf /tmp/fd1002
    
    [ -e /tmp/fd1003 ] || mkfifo /tmp/fd1003
    exec 1003<>/tmp/fd1003
    rm -rf /tmp/fd1003
    
    [ -e /tmp/fd1004 ] || mkfifo /tmp/fd1004
    exec 1004<>/tmp/fd1004
    rm -rf /tmp/fd1004
    
    [ -e /tmp/fd1005 ] || mkfifo /tmp/fd1005
    exec 1005<>/tmp/fd1005
    rm -rf /tmp/fd1005
    
    [ -e /tmp/fd1006 ] || mkfifo /tmp/fd1006
    exec 1006<>/tmp/fd1006
    rm -rf /tmp/fd1006
    
    }
    
    destroy_pipe(){
    exec 1001<&-
    exec 1001>&-
    exec 1002<&-
    exec 1002>&-
    exec 1003<&-
    exec 1003>&-
    exec 1004<&-
    exec 1004>&-
    exec 1005>&-
    exec 1005<&-
    exec 1006<&-
    exec 1006>&-
    }

    work.sh

    # 初始化file descriptor
    #source init_pipe.sh source执行脚本,两个脚本在同一个进程中,执行脚本中的环境变量都可以带到主脚本。
    # ‘.’=fork,开启一个新的子shell,子shell执行完之后返回父shell,不能带回自己的环境变量;
    . init_pipe.sh
    newFun(){
    for((i=0;i<10;i++))
    do
        echo 'new'$i
        sleep 1
        echo $i >& 1001
    done
    }
    
    factFun(){
    for((i=0;i<10;i++))
    do
        read -u 1001 j
        if [ $i -le $j ];then
                echo 'fact'$i
                echo $i>& 1002
                echo $i>& 1003
                echo $i>& 1004
        fi
        sleep 1
    done
    }
    
    lastFun(){
    for((i=0;i<10;i++))
    do
        read -u 1002 j
        if [ $i -le $j ];then
                echo 'last'$i
        fi
        sleep 1
    done
    }
    
    statFun(){
    for((i=0;i<10;i++))
    do
        read -u 1003 j
        if [ $i -le $j ];then
                echo 'stat'$i
        fi
        sleep 1
    done
    }
    retainFun(){
    for((i=0;i<10;i++))
    do
        read -u 1004 j
        if [ $i -le $j ];then
            echo 'retain'$i
        fi
        sleep 1
    done
    }
    
    dvidUserIdFun(){
    for((i=0;i<10;i++))
    do
            echo 'dvidUserId'$i
            echo $i>& 1005
            echo $i>& 1006
        sleep 1
    done
    }
    
    dvidFun(){
    for((i=0;i<10;i++))
    do
        read -u 1005 j
        if [ $i -le $j ];then
                echo 'dvid'$i
        fi
        sleep 1
    done
    }
    
    userIdFun(){
    for((i=0;i<10;i++))
    do
        read -u 1006 j
        if [ $i -le $j ];then
                echo 'userId'$i
        fi
        sleep 1
    done
    }
    ###################################################
    init_pipe
    start_time=`date +%s`
    newFun &
    factFun &
    lastFun &
    statFun &
    retainFun &
    dvidUserIdFun &
    dvidFun &
    userIdFun &
    wait
    end_time=`date +%s`
    echo "TIME:[[ $end_time - $start_time]]"
    
    destroy_pipe
  • 相关阅读:
    BZOJ1066: [SCOI2007]蜥蜴
    BZOJ1934: [Shoi2007]Vote 善意的投票
    BZOJ2321: [BeiJing2011集训]星器
    BZOJ1076: [SCOI2008]奖励关
    BZOJ1821: [JSOI2010]Group 部落划分 Group
    BZOJ3038: 上帝造题的七分钟2
    NOIP2017滚粗记
    BZOJ1087: [SCOI2005]互不侵犯King
    BZOJ1085: [SCOI2005]骑士精神
    BZOJ1295: [SCOI2009]最长距离
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/9897694.html
Copyright © 2011-2022 走看看