shell的並行程式設計:通過啟用多個並行的後台子程序,實現任務的並行處理。
併發程式設計的模式:
簡單模式
批處理模式
輪詢模式
佇列模式
簡單模式
將多個任務放在後台,以子程序的方式進行執行。可以看成是簡單模式的併發程式設計。
#!/bin/bash
function log() >= 2))
dosleep 0.1
joblist=($(jobs -p))
done
do_working $i &
i=$(($i+1))
done
wait
main
執行輸出:
2019-08-28 21:48:42 i am working for 1 seconds.
2019-08-28 21:48:42 i am working for 2 seconds.
2019-08-28 21:48:43 i am working ok.
2019-08-28 21:48:43 i am working for 3 seconds.
2019-08-28 21:48:44 i am working ok.
2019-08-28 21:48:44 i am working for 4 seconds.
2019-08-28 21:48:46 i am working ok.
2019-08-28 21:48:46 i am working for 5 seconds.
2019-08-28 21:48:48 i am working ok.
2019-08-28 21:48:48 i am working for 6 seconds.
2019-08-28 21:48:51 i am working ok.
2019-08-28 21:48:54 i am working ok.
優勢:避免了併發任務執行時間的差異問題,對於效能要求不是特別嚴格的場景,輪詢/睡眠的方式可以解決絕大部分的問題,且這種模式編碼簡單,邏輯直觀。
劣勢:輪詢的方式檢查後台子程序的數量,存在一定的效能損耗。同時,jobs -p並沒有區分子程序的型別。若父程序啟動的後台程序中,存在不同型別的任務,那麼這種方式就不太適合了。
佇列模式
#!/bin/bash
q_fd=8
q_size=2
function fifo_init() ""<>$$.fifo.tmp"
rm -rf $$.fifo.tmp
trap fifo_clean sigint sighup sigquit sigkill
for ((i=0; i
dofifo_release
done
function fifo_free()
function fifo_release()
function log() {
echo "$(date '+%y-%m-%d %h:%m:%s')" $@
function do_working() {
log "i am working for $1 seconds."
sleep $1
log "i am working ok for $1 seconds."
fifo_release
function main() {
fifo_init
for ((i=1; i<=6; ++i))
dofifo_acquire
do_working $i &
done
wait
fifo_free
main
執行結果:
2019-08-28 22:10:16 i am working for 1 seconds.
2019-08-28 22:10:16 i am working for 2 seconds.
2019-08-28 22:10:17 i am working ok for 1 seconds.
2019-08-28 22:10:17 i am working for 3 seconds.
2019-08-28 22:10:18 i am working ok for 2 seconds.
2019-08-28 22:10:18 i am working for 4 seconds.
2019-08-28 22:10:20 i am working ok for 3 seconds.
2019-08-28 22:10:20 i am working for 5 seconds.
2019-08-28 22:10:22 i am working ok for 4 seconds.
2019-08-28 22:10:22 i am working for 6 seconds.
2019-08-28 22:10:25 i am working ok for 5 seconds.
2019-08-28 22:10:28 i am working ok for 6 seconds.
2019-08-28 22:10:28 fifo free ok
優勢:使用命名管道的方式,避免了上面輪詢模式下的效率問題。通過把命名管道看成是fifo佇列,可以從系統層面實現生產者-消費者模式。應用範圍可以覆蓋所有的併發場景。
劣勢:程式設計複雜,需要掌握的系統知識較多。
優化併發任務數根據cpu核心的數量,自動推斷使用幾個後台程序進行併發處理;
併發處理的結果,需要通過乙個佇列儲存起來,以便後續的定位和除錯跟蹤;
參考資料
eval併發 shell shell eval用法
eval可讀取一連串的引數,然後再依引數本身的特性來執行。eval是shell內建命令,可用shell檢視其用法。引數不限數目,彼此之間用分號隔開。eval 引數 eval命令將會首先掃瞄命令列進行所有的置換,然後再執行該命令。該命令適用於那些一次掃瞄無法實現其功能的變數。該命令對變數進行兩次掃瞄。...
Eval 資料繫結
eval內部必須是雙引號,因為它是普通的c 方法。eval可以使用第二個引數格式化,因此例如你就可以寫 barcode欄位儲存的是條形碼號,如果條形號碼為空,則顯示 待審核 否則顯示條形碼 將格式化日期的方法繫結到資料控制項中 protected string gettime object time...
Eval 資料繫結
eval內部必須是雙引號,因為它是普通的c 方法。eval可以使用第二個引數格式化,因此例如你就可以寫 barcode欄位儲存的是條形碼號,如果條形號碼為空,則顯示 待審核 否則顯示條形碼 將格式化日期的方法繫結到資料控制項中 protected string gettime object time...