linux中shell類比多線程執行任務詳解

來源:互聯網
上載者:User

shell本身是不能實現多線程的,但是可以通過啟動子進程,並將子進程放入後台執行來類比多線程,為了在提高指令碼執行效率的同時又不明顯增加負載的作用,還需要對同時放入背景進程數做下限制。

 代碼如下 複製代碼

#!/bin/bash
set -x  # 開啟偵錯模式

#判斷是否有參數
if [ $# != 1 ];then
    echo "您輸入的參數有誤"
    exit -1
fi

# 允許的最大進程數
MAX_THREAD_NUM=5

tmp_fifo_file=/tmp/$$.fifo # 以指令碼啟動並執行當前進程ID號作為檔案名稱
mkfifo "$tmp_fifo_file"    # 建立一個隨機fifo管道檔案
exec 9<>"$tmp_fifo_file"   # 定義檔案描述符9指向這個fifo管道檔案
rm "$tmp_fifo_file"

# 預先寫入指定數量的分行符號到fifo管道檔案中,一個分行符號代表一個進程
for((i=0;i<$MAX_THREAD_NUM;i++));do
     echo
done >&9

# 迴圈讀出url並判斷狀態代碼
while read line
do
{
    # 進程式控制制
    read -u 9 # 從檔案描述符9中讀取行,實際指向fifo管道
    {
        isok=`curl -I -L -m 60 -o /dev/null -s -w %{http_code} $line`
        if [ "$isok" = "200" ];then
            echo $line "OK"
        else
            echo $line $isok
        fi
        echo >&9 # ,當前進程結束,往fifo管道檔案中寫入一個空行
    }&
}
done < $1 wait echo '執行結束' exec 9>&- # 刪除檔案描述符9

exit 0

指令碼的任務是對一個url列表中的網址進行判斷,判斷這些網址是否可以繼續訪問,具體方法是,通過curl擷取http的狀態代碼來判斷。

上面紅色部分{}中的語句被放進子進程中在後台執行,當fifo中5個空行讀完後,迴圈繼續等待 read 中讀取fifo資料,當背景子進程完成任務後,排隊往fifo輸入空行,這樣fifo中又有了資料,迴圈繼續執行。

下面看看shell執行的結果

 代碼如下 複製代碼
# bash scanUrl.sh url.txt
+ '[' 1 '!=' 1 ']'
+ MAX_THREAD_NUM=5
+ tmp_fifo_file=/tmp/111cn.net
+ mkfifo /tmp/111cn.net
+ exec
+ rm /tmp/111cn.net
+ (( i=0 ))
+ (( i<5 ))
+ echo
+ (( i++ ))
+ (( i<5 ))
+ echo
+ (( i++ ))
+ (( i<5 ))
+ echo
+ (( i++ ))
+ (( i<5 ))
+ echo
+ (( i++ ))
+ (( i<5 ))
+ echo
+ (( i++ ))
+ (( i<5 ))
+ read line
+ read -u 9
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9      # fifo檔案中的5個空行讀完了,等待其它子進程寫入fifo
+ isok=200
+ '[' 200 = 200 ']'
+ echo http://111cn.net / OK
http://111cn.net / OK
+ echo          # 這個子進程完成任務,寫入fifo一個空行,啟動一個子進程
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ read -u 9
+ isok=200
+ '[' 200 = 200 ']'
+ echo http://50vip.com/ OK
http://50vip.com/ OK
+ echo
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /info/
+ read line
+ read -u 9
+ isok=200
+ '[' 200 = 200 ']'
+ echo http://361a.net/ OK
http://361a.net/ OK
+ echo
++ curl -I -L -m 60 -o /dev/null -s -w '%{http_code}' http://111cn.net /
+ read line
+ wait         # 輸入檔案中的url都已經處理完成或在子進程中處理,等待所有子進程結束
+ isok=200
+ '[' 200 = 200 ']'
+ echo http://111cn.net / OK
http://111cn.net / OK
+ echo
+ isok=000
+ '[' 000 = 200 ']'
+ echo http://5imovie.org/ 000
http://5imovie.org/ 000
+ echo
+ isok=200
+ '[' 200 = 200 ']'
+ echo http://111cn.net / OK
http://52ixwebhosting.com/ OK
+ echo
+ isok=404
+ '[' 404 = 200 ']'
+ echo http://111cn.net /info/ 404
http://111cn.net /info/ 404
+ echo
+ isok=000
+ '[' 000 = 200 ']'
+ echo http://111cn.net / 000
http://42.hcocoa.com/ 000
+ echo
+ echo $'346211247350241214347273223346235237'
執行結束
+ exec
+ exit 0

下面我們再來看個例子

 代碼如下 複製代碼
#!/bin/bash
function pinghost {
ping $1 -c 1 -w 10 |grep rtt|cut -d “/” -f6
}
tmp_fifofile=”/tmp/$.fifo”   # 指令碼啟動並執行當前進程ID號作為檔案名稱
mkfifo $tmp_fifofile         # 建立一個隨機fifo管道檔案
exec 6<>$tmp_fifofile         # 定義檔案描述符6指向這個fifo管道檔案
rm $tmp_fifofile
thread=10
for ((i=0;i<$thread;i++));do   # for迴圈 往 fifo管道檔案中寫入10個空行
echo
done >&6
while read domain
do
read -u6                  # 從檔案描述符6中讀取行(實際指向fifo管道)
{
pinghost ${domain};      # 執行pinghost函數
echo >&6                      # 再次往fifo管道檔案中寫入一個空行。
}&                                  # 放到後台執行
done</home/miotour/ip.txt
wait                          #因為之前的進程都是後台執行,因此要有wait來等待所有的進程都執行完畢後才算整個指令碼跑完。
exec 6>&-                #刪除檔案描述符6
exit 0

說明:{} 這部分語句被放入後台作為一個子進程執行,這部分幾乎是同時完成的,當fifo中10個空行讀完後 while迴圈
繼續等待 read 中讀取fifo資料,當背景10個子進程後,按次序排隊往fifo輸入空行,這樣fifo中又有了資料,for語句繼續執行。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.