Shell腳本並發及並發數的控制


https://www.jianshu.com/p/701952ffb755

正常情況下,Shell腳本是串行執行的,一條命令執行完才會執行接下來的命令。如下代碼:

# !/bin/bash for i in `seq 1 10` do echo $i done echo "----end----" 

腳本執行的結果如下:

1 2 3 4 5 6 7 8 9 10 ----end---- 

echo $1 命令串行執行,如果命令耗時較長導致總時間較長。如果命令之間沒有互相依賴關系時,可以讓命令並行執行,並行執行的方法就是在命令后加上 & 符號。

# !/bin/bash for i in `seq 1 10` do echo $i & done echo "----end----" 

腳本執行的結果如下:

1 2 3 5 4 ----end---- 10 7 8 9 6 

可以看到,這樣不能保證命令的執行順序,有的時候需要保證for循環所有命令執行完后再向后執行接下來的命令。可以使用 wait 實現

# !/bin/bash for i in `seq 1 10` do echo $i & done wait echo "----end----" 

腳本執行的結果如下:

1 2 3 6 9 10 4 5 7 8 ----end---- 

問題還沒有結束,當需要並行執行的命令數量特別多的時候,特別是執行命令的資源占用較多時,直接用 & 實現並行容易將服務器資源占用打滿,影響其他程序運行。
使用管道和令牌原理實現並發控制。

#!/bin/bash # Step1 創建有名管道 [ -e ./fd1 ] || mkfifo ./fd1 # 創建文件描述符,以可讀(<)可寫(>)的方式關聯管道文件,這時候文件描述符3就有了有名管道文件的所有特性 exec 3<> ./fd1 # 關聯后的文件描述符擁有管道文件的所有特性,所以這時候管道文件可以刪除,我們留下文件描述符來用就可以了 rm -rf ./fd1 # Step2 創建令牌 for i in `seq 1 2`; do # echo 每次輸出一個換行符,也就是一個令牌 echo >&3 done # Step3 拿出令牌,進行並發操作 for line in `seq 1 10`; do read -u3 # read 命令每次讀取一行,也就是拿到一個令牌 { echo $line echo >&3 # 執行完一條命令會將令牌放回管道 }& done wait exec 3<&- # 關閉文件描述符的讀 exec 3>&- # 關閉文件描述符的寫


作者:不智魚
鏈接:https://www.jianshu.com/p/701952ffb755
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

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



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