GNU parallel 筆記

GNU parallel 是一個能夠並行執行任務的 Shell 工具。它是一個 perl 腳本。本文全部的示例在 Bash 環境中有效。linux

初次嘗試

之前雖然知道有這麼個工具,可是一直沒想到要用。今天在刪除個人 Gentoo 系統的 /usr/src 目錄下的舊版本的內核源碼目錄時用了一次,很好用。shell

$ cd /usr/src
$ ls ls -d linux-*
linux-4.8.10-gentoo/  linux-4.8.5-gentoo/  linux-4.8.7-gentoo/
linux-4.8.12-gentoo/  linux-4.8.6-gentoo/  linux-4.8.9-gentoo/

linux-4.8.12-gentoo 是我目前正在使用的內核版本的源碼,我想只保留它,將其餘的源碼目錄都刪掉。這些源碼目錄中除了包含內核源碼文件以外,還包含我編譯時產生的中間文件,太佔硬盤空間,每一個源碼目錄差很少要用 1.2 GB 的空間。segmentfault

以前要刪,記不起 bash 的 for 循環語法時,就是一個一個的 rm -rf。沒忘記 for 的語法時,就這樣刪:數組

$ for i in linux-4.8.{5,6,7,8,9,10}-gentoo ; do sudo rm -rf $i ; done

之因此老是忘記 bash 的 for 語法,是由於平時使用的 Shell 是 fish。fish 的 for 語法與 bash 不一樣。結果,它們兩個的 for 語法我都記不住。bash

對於這種刪除文件或目錄的特定任務而言,更簡單的作法是:工具

$ sudo rm -rf linux-4.8.{5,6,7,8,9,10}-gentoo

如今用 GNU parallel,就簡單多了:oop

$ sudo parallel rm -rf ::: linux-4.8.{5,6,7,8,9,10}-gentoo

更重要的是,若是 parallel所執行的任務是並行的。對於比較慢的任務,在多核機器上,這是個福音。測試

若是你沒東西能夠刪,能夠試試下面這條對系統無任何危害的命令,體驗一下 parallel:動畫

$ parallel echo ::: linux-4.8.{5,6,7,8,9,10}-gentoo

並行生成 povray 動畫的各幀

假設 povray 的渲染腳本爲 foo.pov,動畫配置文件爲 foo-{1,2,3,4}.ini。並行執行 4 個 povray 進程,繪製一份被劃分爲四組的 30 幀畫面的動畫:spa

$ parallel povray ::: foo-{1,2,3,4}.ini
$ convert -delay 10 -loop 0 foo*.png foo.gif

可用下面的命令製做 povray 命令所須要的 4 份 .ini 文件的內容:

$ cat << EOF > foo.ini
Cyclic_Animation=on
Input_File_Name=foo.pov

Initial_Frame=1
Final_Frame=30
Initial_Clock=1
Final_Clock=0

EOF
$ seq 4 | parallel cp foo.ini foo-{}.ini
$ parallel --link 'echo Subset_Start_Frame={1} | tee -a foo-{2}.ini' ::: 1 8 15 22 ::: 1 2 3 4
$ parallel --link 'echo Subset_End_Frame={1} | tee -a foo-{2}.ini' ::: 7 14 21 30 ::: 1 2 3 4

測試所用的三維模型,在一臺四個 CPU 核心的機器上,使用單個 povray 進程,渲染 60 幀,須要 207 秒。將這 60 幀劃分爲 4 組,而後用 parallel 調用 4 個 povray 進程進行渲染,只須要 92 秒。雖然並行沒有預想的那樣快,不過鑑於單個 povray 進程在光線跟蹤運算過程當中用了 2 個線程,若個人機器的 CPU 核心數能有 8 個,那麼渲染時間應該能降到 50 秒左右。

povray 動畫並行渲染結果

並行下載及 zero 的並行化

這個只是在咱們屋裏有點用。

$ parallel 'wget http://192.168.0.7:8080/meta-doc/agn_{}.zero' ::: array list points kd_tree bkd_tree
$ parallel 'zero -m night -e "agn_{}.h, agn_{}.c" agn_{}.zero' ::: array list points kd_tree bkd_tree

避免兩次載入 parallel 進程,上述兩條命令能夠「疊加」到一塊兒:

$ parallel 'wget http://192.168.0.7:8080/meta-doc/agn_{}.zero ; \
            zero -m night -e "agn_{}.h, agn_{}.c"  agn_{}.zero' \
            ::: array list points kd_tree bkd_tree

zero 是什麼東西,這須要看「zero 的故事系列」。

shell 的變量與數組的傳遞

shell 中的變量與數組可經過 env_parallel 傳遞給 parallel 程序。例如:

$ LOCATION="http://192.168.0.7:8080/meta-doc"
$ ZERO_FILES=(array list points kd_tree bkd_tree)
$ source `which env_parallel.bash`
$ env_parallel 'echo $LOCATION/agn_{}.zero' ::: ${ZERO_FILES[*]}
http://192.168.0.7:8080/meta-doc/agn_array.zero
http://192.168.0.7:8080/meta-doc/agn_list.zero
http://192.168.0.7:8080/meta-doc/agn_points.zero
http://192.168.0.7:8080/meta-doc/agn_kd_tree.zero
http://192.168.0.7:8080/meta-doc/agn_bkd_tree.zero

應該尚未完,待續……

相關文章
相關標籤/搜索