国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > PowerShell > 正文

PowerShell中Job相關(guān)命令及并行執(zhí)行任務(wù)詳解

2020-03-26 18:52:08
字體:
供稿:網(wǎng)友

前言

在 PowerShell 中可以輕松的執(zhí)行后臺任務(wù)并且讓多個后臺任務(wù)并行執(zhí)行。本文介紹 PowerShell 中 Job 相關(guān)的一些命令,并通過 demo 演示如何在后臺同時執(zhí)行多個任務(wù)。下面話不多說了,來一起看看詳細的介紹吧。

PowerShell 中執(zhí)行后臺任務(wù)的模式

下圖描述了在 PowerShell 中執(zhí)行后臺任務(wù)的進程模型(此圖來自互聯(lián)網(wǎng)):

powershell,并行,job,命令

首先我們需要一個 PowerShell 進程執(zhí)行與用戶交互的命令,比如執(zhí)行 Start-Job 命令運行一個后臺任務(wù)。每一個這樣的后臺任務(wù)都會在一個新啟動的 PowerShell 進程中執(zhí)行。所以,如果我們同時啟動三個后臺任務(wù),那么一共有四個 PowerShell 進程在同時運行。

Job 相關(guān)的命令

Start-Job 命令會啟動一個運行在后臺的任務(wù)。注意,每通過 Start-Job 命令運行一個任務(wù)都會創(chuàng)建一個單獨的 PowerShell 進程。

Stop-Job 命令用來停止一個正在運行的后臺任務(wù)(由 Start-Job 啟動的任務(wù))。

Get-Job 命令用來獲得當(dāng)前 session 中的后臺任務(wù)對象。

Wait-Job 命令阻塞當(dāng)前的執(zhí)行流程,等待指定的后臺任務(wù)執(zhí)行結(jié)束。

Receive-Job 命令用來獲得后臺執(zhí)行任務(wù)的執(zhí)行結(jié)果。比如在一個后臺任務(wù)結(jié)束時,可以通過 Receive-Job 來得到結(jié)果,并輸出任務(wù)執(zhí)行時的 output。

Remove-Job 命令刪除當(dāng)前 session 中的已經(jīng)完成的任務(wù)。當(dāng)一個任務(wù)運行結(jié)束后,它并不會被自動刪除,除非你調(diào)用 Remove-Job 命令進行刪除,或者是關(guān)閉這個 session。如果使用 Remove-Job 刪除一個正在運行的任務(wù),命令會運行失敗。此時需要先使用 Stop-Job 命令先停止任務(wù),然后再用 Remove-Job 進行刪除。

在后臺執(zhí)行任務(wù)

如果只是啟動一個后臺執(zhí)行的任務(wù),不需要知道任務(wù)執(zhí)行的結(jié)果,也不關(guān)心任務(wù)何時執(zhí)行結(jié)束,那么僅僅使用 Start-Job 命令啟動任務(wù)的執(zhí)行就可以了:

> Start-Job -ScriptBlock { sleep 5 }

啟動單個任務(wù)并等待任務(wù)結(jié)束

多數(shù)情況下我們是需要知道任務(wù)的結(jié)束時間的,此時可以通過 Wait-Job 命令阻塞執(zhí)行流程,直到等待的任務(wù)結(jié)束:

> Start-Job -ScriptBlock { sleep 5; Write-Host "Hello world."; } | Wait-Job

powershell,并行,job,命令

注意:上面的內(nèi)容是由 Wait-Job 命令輸出的,當(dāng)時任務(wù)的狀態(tài)為 "Completed"。

更進一步,我們還想要獲得任務(wù)執(zhí)行過程中的輸出。這時我們就需要用到 Receive-Job 命令。你可以在任務(wù)啟動后的任何時刻執(zhí)行 Receive-Job 命令,但是如果想要得到完整的輸出,就需要在任務(wù)結(jié)束后調(diào)用,此時需要配合 Wait-Job 命令一起使用:

$job = Start-Job -ScriptBlock { sleep 5; Write-Host "Hello world."; }Wait-Job $jobReceive-Job -Job $job

把上面的代碼保存到文件 mytask.ps1 中執(zhí)行:

powershell,并行,job,命令

Receive-Job 命令輸出了我們在后臺執(zhí)行的任務(wù)的 output。

在后臺執(zhí)行多個任務(wù)并等待結(jié)束

因為 Start-Job 命令是非阻塞的,所以理論上我們可以執(zhí)行任意多次從而啟動很多的后臺任務(wù)。和等待單個任務(wù)相同,仍然可以使用 Wait-Job 命令來等待所有的任務(wù)結(jié)束,不過此時需要配合 Get-Job 命令一起使用:

> Get-Job | Wait-Job

更常用的方式是我們在 while 循環(huán)中不斷的檢查任務(wù)的狀態(tài),當(dāng)所有任務(wù)的狀態(tài)都是 "Completed" 時表示全部任務(wù)執(zhí)行結(jié)束:

Remove-Job *#測試計時開始$start_time = (Get-Date)Start-Job -ScriptBlock { sleep 9; Write-Host "Hello myJob1."; } -Name "myJob1"Start-Job -ScriptBlock { sleep 5; Write-Host "Hello myJob2."; } -Name "myJob2"$taskCount = 2while($taskCount -gt 0){ foreach($job in Get-Job) {  $state = [string]$job.State  if($state -eq "Completed")  {    Write-Host($job.Name + " 已經(jīng)完成")   Receive-Job $job   $taskCount--   Remove-Job $job  } } sleep 1}"所有任務(wù)已完成" #得出任務(wù)運行的時間(New-TimeSpan $start_time).totalseconds

把上面的代碼保存到 mytask.ps1 文件中并執(zhí)行:

powershell,并行,job,命令

代碼中我們給每個任務(wù)起了名字,并在 while 循環(huán)中不斷的使用 Get-Job 命令檢查任務(wù)當(dāng)前的狀態(tài),如果發(fā)現(xiàn)任務(wù)的狀態(tài)為 "Completed",就通過 Remove-Job 命令刪除它,并在刪除前打印任務(wù)的名稱和 output。

封裝一個執(zhí)行后臺任務(wù)的函數(shù)

下面我們用封裝一個簡單的函數(shù)來并行執(zhí)行多個任務(wù):

function Run-Tasks{ Param (  $taskArr,  $parallelcount=1 ) #測試計時開始 $startTime = (Get-Date)  #移除本次會話中已有的所有后臺任務(wù) Remove-Job * # 使用變量 $taskCount 保存還沒有執(zhí)行完成的任務(wù)數(shù) $taskCount = $taskArr.Length  #判斷設(shè)定的并行任務(wù)數(shù)是否超過當(dāng)前任務(wù)隊列中的任務(wù)數(shù) if($parallelCount -gt $taskArr.Length) {  $parallelCount = $taskArr.Length } #啟動初始任務(wù) foreach($i in 1..$parallelCount) {  Start-Job $taskArr[$i - 1] -Name "task$i" } #初始任務(wù)完成后開始的任務(wù) $nextIndex = $parallelCount #當(dāng)任務(wù)隊列中還有任務(wù)時不斷輪詢已建立的任務(wù),當(dāng)一個后臺任務(wù)結(jié)束時刪除這個任務(wù), #然后從任務(wù)隊列中取出下一個任務(wù)進行執(zhí)行,然后等待所有任務(wù)執(zhí)行完成。 while(($nextIndex -lt $taskArr.Length) -or ($taskCount -gt 0)) {  foreach($job in Get-Job)  {   $state = [string]$job.State   if($state -eq "Completed")   {     Write-Host($job.Name + " 已經(jīng)完成,結(jié)果如下:")    Receive-Job $job    Remove-Job $job    $taskCount--    if($nextIndex -lt $taskArr.Length)    {      $taskNumber = $nextIndex + 1     Start-Job $taskArr[$nextIndex] -Name "task$taskNumber"     $nextIndex++    }   }  }  sleep 1 } "所有任務(wù)已完成" #得出任務(wù)運行的時間 (New-TimeSpan $startTime).totalseconds}

上面的函數(shù)會在后臺執(zhí)行用戶的任務(wù),然后等待所有的任務(wù)執(zhí)行結(jié)束。并且用戶可以指定同時執(zhí)行的任務(wù)的個數(shù),在任務(wù)執(zhí)行完成后,輸出任務(wù)的 output。接下來讓我們嘗試使用這個函數(shù)執(zhí)行一些任務(wù):

#定義 6 個任務(wù)$task1 = {sleep 12; Write-Host "Hello myJob1."; }$task2 = {sleep 5; Write-Host "Hello myJob2."; }$task3 = {sleep 8; Write-Host "Hello myJob3."; }$task4 = {sleep 3; Write-Host "Hello myJob4."; }$task5 = {sleep 20; Write-Host "Hello myJob5."; }$task6 = {sleep 15; Write-Host "Hello myJob6."; } #將 6 個任務(wù)寫入到一個數(shù)組中作為任務(wù)隊列$taskArr = $task1, $task2, $task3, $task4, $task5, $task6#運行數(shù)組中的任務(wù),允許同時運行 4 個任務(wù)Run-Tasks -taskArr $taskArr -parallelcount 4

下面是運行的結(jié)果:

powershell,并行,job,命令

總結(jié)

能夠隨心所欲的在后臺執(zhí)行任務(wù)是一件感覺非常棒的事情!當(dāng)然,對于工作來說你能夠把事情做得又快又好(又好可不敢說)。本文只是提供了一個簡單的運行并行任務(wù)的 demo,省略了異常處理等重要內(nèi)容,但這已經(jīng)足夠您開始 PowerShell 并行任務(wù)之旅了。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 广元市| 大厂| 荃湾区| 达孜县| 祁东县| 巴青县| 东港市| 西藏| 肥西县| 双牌县| 博罗县| 望谟县| 秦安县| 克东县| 吴桥县| 镶黄旗| 容城县| 宁强县| 杭锦旗| 团风县| 承德市| 屯留县| 连云港市| 泽普县| 肇州县| 常宁市| 兴隆县| 武冈市| 临漳县| 临沂市| 碌曲县| 库尔勒市| 宜良县| 简阳市| 台前县| 固阳县| 达州市| 云安县| 广州市| 博罗县| 安远县|