shell 並發執行任務


 

#!/bin/bash
# ref: https://blog.csdn.net/spch2008/article/details/51433353
token(){
    pid=$1
    # 判斷是否有傳入pid
    if [ -z "${pid}" ]
    then
        echo "please input pid"
        exit 1
    fi
    
    # 設置並發數,默認為5
    concurrency=5
    if [ -n "$2" ]
    then
        concurrency=$2
        echo "Concurrency: $2"
    fi

    # 創建有名管道,如果fd1不存在則創建
    [ -e /tmp/fd1 ] || mkfifo /tmp/fd1
    # 創建文件描述符,以可讀(<)可寫(>)的方式關聯管道文件,這時候文件描述符999就有了有名管道文件的所有特性
    # 為了讓程序有一定的擴展性,不想寫死fd,因而引入了變量。
    # 因而引入eval命令,強制shell進行變量展開。
    # eval exec "${fd}>file"簡單的說,eval將右邊參數整體作為一個命令,進行變量的替換,然后將替換后的輸出結果給shell去執行。
    eval exec "${pid}<>/tmp/fd1"
    # 關聯后的文件描述符擁有管道文件的所有特性,所以這時候管道文件可以刪除,我們留下文件描述符來用就可以了
    [ -e /tmp/fd1 ] && rm -f /tmp/fd1

    # 初始化並行數
    for ((i=1;i<=3;i++))
    do
        # &999代表引用文件描述符999,這條命令代表往管道里面放入了一個"令牌"
        echo ${i}>&${pid}
    done
}

main(){
    pid=5
    start_time=`date +%s`
    # 生成管道文件
    token ${pid}

    # 循環獲取服務包名
    for file_name in `ls /root/spark/dependency/*.jar|head -10`
    do
        # 獲取令牌
        read -u${pid} name
        {
            # 根據文件名去掉版本后綴,獲得服務名
            # svc_name=${file_name%0.0.1*}
            # 獲取啟動參數
            # get_para
            # 執行重啟
            # one_restart
            # 這一次命令執行到最后,把令牌放回管道
            echo "pipi_num: ${name}, file_name: ${file_name}"
            sleep 1
            echo ${name}>&${pid}
        } &
    done

    wait
    # 定義腳本運行的結束時間
    stop_time=`date +%s`
    echo "TIME:`expr ${stop_time} - ${start_time}`"
    # 關閉文件描述符的讀
    eval exec "${pid}<&-"
    # 關閉文件描述符的寫
    eval exec "${pid}>&-"
}

main

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM