在 powershell 中可以輕鬆的執行後台任務並且讓多個後台任務並行執行。本文介紹 powershell 中 job 相關的一些命令,並通過 demo 演示如何在後台同時執行多個任務。
下圖描述了在 powershell 中執行後台任務的程序模型(此圖來自網際網路):
首先我們需要乙個 powershell 程序執行與使用者互動的命令,比如執行 start-job 命令執行乙個後台任務。每乙個這樣的後台任務都會在乙個新啟動的 powershell 程序中執行。所以,如果我們同時啟動三個後台任務,那麼一共有四個 powershell 程序在同時執行。
start-job命令會啟動乙個執行在後台的任務。注意,每通過 start-job 命令執行乙個任務都會建立乙個單獨的 powershell 程序。
stop-job命令用來停止乙個正在執行的後台任務(由 start-job 啟動的任務)。
get-job命令用來獲得當前 session 中的後台任務物件。
wait-job命令阻塞當前的執行流程,等待指定的後台任務執行結束。
receive-job命令用來獲得後台執行任務的執行結果。比如在乙個後台任務結束時,可以通過 receive-job 來得到結果,並輸出任務執行時的 output。
remove-job命令刪除當前 session 中的已經完成的任務。當乙個任務執行結束後,它並不會被自動刪除,除非你呼叫 remove-job 命令進行刪除,或者是關閉這個 session。如果使用 remove-job 刪除乙個正在執行的任務,命令會執行失敗。此時需要先使用 stop-job 命令先停止任務,然後再用 remove-job 進行刪除。
如果只是啟動乙個後台執行的任務,不需要知道任務執行的結果,也不關心任務何時執行結束,那麼僅僅使用 start-job 命令啟動任務的執行就可以了:
> start-job -scriptblock多數情況下我們是需要知道任務的結束時間的,此時可以通過 wait-job 命令阻塞執行流程,直到等待的任務結束:
注意上面的內容是由 wait-job 命令輸出的,當時任務的狀態為 "completed"。
更進一步,我們還想要獲得任務執行過程中的輸出。這時我們就需要用到 receive-job 命令。你可以在任務啟動後的任何時刻執行 receive-job 命令,但是如果想要得到完整的輸出,就需要在任務結束後呼叫,此時需要配合 wait-job 命令一起使用:
$job = start-job -scriptblock把上面的**儲存到檔案 mytask.ps1 中執行:wait-job $job
receive-job -job $job
receive-job 命令輸出了我們在後台執行的任務的 output。
因為 start-job 命令是非阻塞的,所以理論上我們可以執行任意多次從而啟動很多的後台任務。和等待單個任務相同,仍然可以使用 wait-job 命令來等待所有的任務結束,不過此時需要配合 get-job 命令一起使用:
> get-job | wait-job更常用的方式是我們在 while 迴圈中不斷的檢查任務的狀態,當所有任務的狀態都是 "completed" 時表示全部任務執行結束:
remove-job *把上面的**儲存到 mytask.ps1 檔案中並執行:#測試計時開始
$start_time = (get-date)
start-job -scriptblock -name "
myjob1
"start-job -scriptblock -name "
myjob2
"$taskcount = 2
while($taskcount
-gt 0)
}sleep 1}
"所有任務已完成"#
得出任務執行的時間
(new-timespan $start_time).totalseconds
**中我們給每個任務起了名字,並在 while 迴圈中不斷的使用 get-job 命令檢查任務當前的狀態,如果發現任務的狀態為 "completed",就通過 remove-job 命令刪除它,並在刪除前列印任務的名稱和 output。
下面我們用封裝乙個簡單的函式來並行執行多個任務:
function run-tasks上面的函式會在後台執行使用者的任務,然後等待所有的任務執行結束。並且使用者可以指定同時執行的任務的個數,在任務執行完成後,輸出任務的 output。接下來讓我們嘗試使用這個函式執行一些任務:#啟動初始任務
foreach($i
in 1..$parallelcount
)
#初始任務完成後開始的任務
$nextindex = $parallelcount
#當任務佇列中還有任務時不斷輪詢已建立的任務,當乙個後台任務結束時刪除這個任務,
#然後從任務佇列中取出下乙個任務進行執行,然後等待所有任務執行完成。
while(($nextindex
-lt$taskarr.length) -or ($taskcount
-gt 0))}}
sleep 1}
"所有任務已完成"#
得出任務執行的時間
(new-timespan $starttime
).totalseconds
}
#下面是執行的結果:定義 6 個任務
$task1 =
$task2 =
$task3 =
$task4 =
$task5 =
$task6 =
#將 6 個任務寫入到乙個陣列中作為任務佇列
$taskarr = $task1, $task2, $task3, $task4, $task5, $task6
#執行陣列中的任務,允許同時執行 4 個任務
run-tasks -taskarr $taskarr -parallelcount 4
能夠隨心所欲的在後台執行任務是一件感覺非常棒的事情!當然,對於工作來說你能夠把事情做得又快又好(又好可不敢說)。本文只是提供了乙個簡單的執行並行任務的 demo,省略了異常處理等重要內容,但這已經足夠您開始 powershell 並行任務之旅了。
參考:
《windows powershell 實戰第二版》
powershell:簡單實現並行任務的指令碼
Jenkins pipeline 並行執行任務流
筆者在 jenkins 在宣告式 pipeline 中並行執行任務 一文中介紹了如何在宣告式 pipeline 中執行並行的任務。前一段時間,jenkins 發布了 1.3 版的宣告式 pipeline declarative pipeline 這個版本繼續增強了並行執行任務的能力 並行執行的任務可...
AsyncTask並行執行
使用asynctask時發現乙個奇怪的現象,即建立多個任務的時候,他是乙個乙個按順序執行的,查資料之後發現 在1.5中初始引入的時候,asynctask 執行 asynctask.execute 起來是順序的,當同時執行多個 asynctask的時候,他們會按照順序乙個乙個執行。前面乙個執行完才會執...
ORACLE 的並行執行
1.並行查詢 例如 select count from big table 未設定並行查詢時,這個查詢是典型的序列查詢,不設計並行化,可以用 select from big table dbms xplan.display 檢視一下執行計畫。啟用並行查詢方法多種,可直接在查詢中使用乙個提示,或者修改...