1. 程式人生 > 其它 >分享一個入門級可控多執行緒shell指令碼方案

分享一個入門級可控多執行緒shell指令碼方案

說到 shell 可控多執行緒,網上分享的大部分是管道控制的方案。這種方案,張戈部落格也曾經實戰並分享過一次:《Shell+Curl 網站健康狀態檢查指令碼,抓出中國部落格聯盟失聯站點》,感興趣的朋友可以看看。

下面張戈部落格再分享另一種更容易理解的入門級可控多執行緒 shell 指令碼方案:任務切割、各個擊破。

先來 1 段場景描述:

某日,在鵝廠接到了這個任務,需要在 Linux 伺服器中,對幾千個 IP 進行一次 Ping 檢測,只要取得 ping 可達的 IP 就好。如果單個 IP 去 ping 測試,雖然也可以完成任務,幾千個 IP 還好了,如果更多呢?

鑑於這個 case 簡單程度,第一時間先放棄了以前用過的管道方案,而是採用了各個擊破的思想。

簡單思路:

按照任務切割的“戰略思想”,我先將這幾千 IP 存入一個 iplist 檔案,然後寫一個分割函式,將這個檔案分成多份臨時 IP 清單,最後,用多執行緒遍歷這些臨時 IP 檔案即可變相實現多執行緒了。

具體程式碼:

#!/bin/sh
#文字分割函式:將文字$1按份數$2進行分割
SplitFile()
{
    linenum=`wc -l $1 |awk '{print $1}'`
    if [[ $linenum -le $2 ]]
    then
        echo "The lines of this file is less then $2, Are you kidding me..."
        exit
    fi
    Split=`expr $linenum / $2`
    Num1=1
    FileNum=1
    test -d SplitFile || mkdir -p SplitFile
    rm -rf SplitFile/*
    while [ $Num1 -lt $linenum ]
    do
        Num2=`expr $Num1 + $Split`
        sed -n "${Num1}, ${Num2}p " $1 > SplitFile/$1-$FileNum
        Num1=`expr $Num2 + 1`
        FileNum=`expr $FileNum + 1`
    done
}

#Define some variables
SPLIT_NUM=${1:-10} #引數1表示分割成多少份即,開啟多少個執行緒,預設10個
FILE=${2:-iplist}  #引數2表示分割的物件,預設iplist檔案

#分割檔案
SplitFile $FILE $SPLIT_NUM

#迴圈遍歷臨時IP檔案
for iplist in $(ls ./SplitFile/*)
do
    #迴圈ping測試臨時IP檔案中的ip(丟後臺)
    cat $iplist | while read ip
    do
        ping -c 4 -w 4 $ip >/dev/null && echo $ip | tee -ai okip.log #ping 可達的IP則寫入日誌
    done &     #在while迴圈後面加上&符號,讓這個巢狀迴圈在後臺執行
done

將程式碼儲存為 ping.sh 之後,執行  sh ping.sh  iplist 100 的過程如下:

先將 iplist 切割成 100 份,存放在 SplitFile 資料夾中 然後,通過 for 迴圈讀取這些分割檔案,並在後臺使用 while 迴圈對其中 ip 執行 ping 命令。

由於 while 是丟後臺的, 所以 for 迴圈會一次性執行 100 個 while,相當於開啟了 100 個執行緒,速度自然不可同日而語矣。

其中,切割的份數即你想要開啟的多執行緒數量,很明顯,這種任務分割的思路雖然沒有管道方案來的高大上,但是其思想更加簡單易懂,而且通用性也更好,適合入門級的簡單多執行緒任務。