PowerShell 並行執行任務

2022-01-13 04:38:43 字數 3717 閱讀 9715

在 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 

wait-job $job

receive-job -job $job

把上面的**儲存到檔案 mytask.ps1 中執行:

receive-job 命令輸出了我們在後台執行的任務的 output。

因為 start-job 命令是非阻塞的,所以理論上我們可以執行任意多次從而啟動很多的後台任務。和等待單個任務相同,仍然可以使用 wait-job 命令來等待所有的任務結束,不過此時需要配合 get-job 命令一起使用:

> get-job | wait-job
更常用的方式是我們在 while 迴圈中不斷的檢查任務的狀態,當所有任務的狀態都是 "completed" 時表示全部任務執行結束:

remove-job *

#測試計時開始

$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

把上面的**儲存到 mytask.ps1 檔案中並執行:

**中我們給每個任務起了名字,並在 while 迴圈中不斷的使用 get-job 命令檢查任務當前的狀態,如果發現任務的狀態為 "completed",就通過 remove-job 命令刪除它,並在刪除前列印任務的名稱和 output。

下面我們用封裝乙個簡單的函式來並行執行多個任務:

function run-tasks

#啟動初始任務

foreach($i

in 1..$parallelcount

)

#初始任務完成後開始的任務

$nextindex = $parallelcount

#當任務佇列中還有任務時不斷輪詢已建立的任務,當乙個後台任務結束時刪除這個任務,

#然後從任務佇列中取出下乙個任務進行執行,然後等待所有任務執行完成。

while(($nextindex

-lt$taskarr.length) -or ($taskcount

-gt 0))}}

sleep 1}

"所有任務已完成"#

得出任務執行的時間

(new-timespan $starttime

).totalseconds

}

上面的函式會在後台執行使用者的任務,然後等待所有的任務執行結束。並且使用者可以指定同時執行的任務的個數,在任務執行完成後,輸出任務的 output。接下來讓我們嘗試使用這個函式執行一些任務:

#

定義 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 檢視一下執行計畫。啟用並行查詢方法多種,可直接在查詢中使用乙個提示,或者修改...