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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。