在項目過程中,我們常常需要對大量文件進行批量處理。然而,如果每個文件都需要一定的處理時間,而文件數量又很大,逐個的處理會耗費大量的時間,大大影響工作的效率。這時,如果各個文件的處理是相互獨立的話,我們自然希望多個文件能夠並行化地進行處理,最大限度地利用計算機資源來提高工作效率。
本文介紹兩種最爲常見的利用Bash腳本實現並行化的方法。值得一提的是,由於硬件條件的限制,我們通常會對並行化的進程數目進行控制。(博主便曾因爲佔用太多公共資源而遭到投訴了。。)
——————————————————————————————————————————————————————
- 後臺 —— 最樸素的並行化
- FIFO —— 常見的進程控制方法
- xargs —— 逆天的方法
1. 後臺操作
2. FIFO 命名管道
- 什麼是FIFO?
FIFO(命名管道)是一種進程之間進行通信的機制,它是一種特殊的文件類型,可以像平常的文件一樣進行類似的讀寫操作,但又像匿名管道一樣具有進程通信的功能。命名管道相對於匿名管道的優勢在於,不要求進程之間具有親緣關係,能夠實現無關進程之間的通信。
- 如何用FIFO實現並行化?
爲了實現多個進程並行化,我們創建一個FIFO文件作爲進程池,並通過設置一定數目的“令牌”實現併發進程的數目。每個進程依次進入進程池領取“令牌”,若領取成功(有空餘令牌)則運行,完成後歸還令牌;若領取失敗,則等待其它進程釋放令牌。
閒話少說,我們直接看代碼吧:
<pre name="code" class="plain">Nproc=3 # the limit number of processes
Pfifo="/tmp/$$.fifo" # create a fifo type file
mkfifo $Pfifo # create a named pipe
exec 6<>$Pfifo # fd is 6
rm -f $Pfifo
# Initialize the pipe
for((i=1; i<=$Nproc; i=i+1)); do
echo
done >&6
filelist="text.txt"
# Loop
while read line
do
read -u6
{
./test.sh $fn
echo >&6
} &
done < $filelist
wait # waiting for all the background processes finished
exec 6>&-
我們來逐行分析一下:
1. Nproc=3 設定同時執行的進程數上限
2. 新建一個後綴爲fifo的FIFO文件,以PID作爲文件名以避免出現重名情況
3. mkfifo命令,以上面的文件名創建一個命名管道
4. 以讀寫方式打開命名管道,並設置文件標識符爲6
5. 刪除FIFO文件,可有可無
8~10. 往命名管道中寫入Nproc個空行,用來模擬Nproc個令牌
16. 從命名管道中讀取一行,模擬領取一個令牌。由於FIFO特殊的讀寫機制,若沒有空餘的行可以讀取,則進程會等待直至有可以讀取的空餘行
17~20. 若領取到令牌,運行核心程序段,完成後往命名管道寫入一行,模擬歸還令牌操作;這些操作都是在後臺完成,故之後加上 & 命令
23. 等待所有後臺進程完成
24. 釋放文件標識符
3. xargs
xargs可以理解爲一個用於傳遞參數列表的命令,結合 cat 和 pipe 命令,我們可以高效地將文件中每行內容作爲程序的輸入參數並實現並行化。繼續沿用上面的例子,我們只需要寫這麼一行代碼:
cat text.txt | xargs -L 1 -P 3 -I {} ./test.sh {}
難以置信?我們來寫個小腳本測試一下它的效果吧:
實驗結果:
That's all! 意猶未盡?那我們再來看幾個小例子,體會一下xargs命令的強大之處吧!
- 刪除文件名包含空格的文件
find . -names "*.txt" -print0 | xargs -0 rm -rf
- 結合 grep 命令
find . -name '*.c' | xargs grep 'stdlib.h'
Reference:
-
Bash腳本實現批量作業並行化:http://blog.sciencenet.cn/blog-548663-750136.html
-
Linux下進程通信:命名管道: http://cpp.ezbty.org/content/science_doc/linux下進程間通信:命名管道_mkfifo
-
進程間通信——使用匿名管道: http://blog.csdn.net/ljianhui/article/details/10168031
-
進程間通信——使用命名管道:http://blog.csdn.net/ljianhui/article/details/10202699