人妖在线一区,国产日韩欧美一区二区综合在线,国产啪精品视频网站免费,欧美内射深插日本少妇

新聞動(dòng)態(tài)

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

發(fā)布日期:2022-01-15 08:52 | 文章來(lái)源:站長(zhǎng)之家

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

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

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

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

Job 相關(guān)的命令

Start-Job 命令會(huì)啟動(dòng)一個(gè)運(yùn)行在后臺(tái)的任務(wù)。注意,每通過(guò) Start-Job 命令運(yùn)行一個(gè)任務(wù)都會(huì)創(chuàng)建一個(gè)單獨(dú)的 PowerShell 進(jìn)程。

Stop-Job 命令用來(lái)停止一個(gè)正在運(yùn)行的后臺(tái)任務(wù)(由 Start-Job 啟動(dòng)的任務(wù))。

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

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

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

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

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

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

> Start-Job -ScriptBlock { sleep 5 }

啟動(dòng)單個(gè)任務(wù)并等待任務(wù)結(jié)束

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

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

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

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

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

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

Receive-Job 命令輸出了我們?cè)诤笈_(tái)執(zhí)行的任務(wù)的 output。

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

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

> Get-Job | Wait-Job

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

Remove-Job *
#測(cè)試計(jì)時(shí)開(kāi)始
$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 = 2
while($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ù)運(yùn)行的時(shí)間
(New-TimeSpan $start_time).totalseconds

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

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

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

下面我們用封裝一個(gè)簡(jiǎn)單的函數(shù)來(lái)并行執(zhí)行多個(gè)任務(wù):

function Run-Tasks
{
 Param
 (
  $taskArr,
  $parallelcount=1
 )
 #測(cè)試計(jì)時(shí)開(kāi)始
 $startTime = (Get-Date)
  #移除本次會(huì)話中已有的所有后臺(tái)任務(wù)
 Remove-Job *
 # 使用變量 $taskCount 保存還沒(méi)有執(zhí)行完成的任務(wù)數(shù)
 $taskCount = $taskArr.Length
 
 #判斷設(shè)定的并行任務(wù)數(shù)是否超過(guò)當(dāng)前任務(wù)隊(duì)列中的任務(wù)數(shù)
 if($parallelCount -gt $taskArr.Length)
 {
  $parallelCount = $taskArr.Length
 }
 #啟動(dòng)初始任務(wù)
 foreach($i in 1..$parallelCount)
 {
  Start-Job $taskArr[$i - 1] -Name "task$i"
 }
 #初始任務(wù)完成后開(kāi)始的任務(wù)
 $nextIndex = $parallelCount
 #當(dāng)任務(wù)隊(duì)列中還有任務(wù)時(shí)不斷輪詢已建立的任務(wù),當(dāng)一個(gè)后臺(tái)任務(wù)結(jié)束時(shí)刪除這個(gè)任務(wù),
 #然后從任務(wù)隊(duì)列中取出下一個(gè)任務(wù)進(jìn)行執(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ù)運(yùn)行的時(shí)間
 (New-TimeSpan $startTime).totalseconds
}

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

#定義 6 個(gè)任務(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 個(gè)任務(wù)寫(xiě)入到一個(gè)數(shù)組中作為任務(wù)隊(duì)列
$taskArr = $task1, $task2, $task3, $task4, $task5, $task6
#運(yùn)行數(shù)組中的任務(wù),允許同時(shí)運(yùn)行 4 個(gè)任務(wù)
Run-Tasks -taskArr $taskArr -parallelcount 4

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

總結(jié)

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

參考:

《Windows PowerShell 實(shí)戰(zhàn)第二版》
Powershell:簡(jiǎn)單實(shí)現(xiàn)并行任務(wù)的腳本

版權(quán)聲明:本站文章來(lái)源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請(qǐng)保持原文完整并注明來(lái)源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非www.sddonglingsh.com所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來(lái)源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來(lái),僅供學(xué)習(xí)參考,不代表本站立場(chǎng),如有內(nèi)容涉嫌侵權(quán),請(qǐng)聯(lián)系alex-e#qq.com處理。

相關(guān)文章

實(shí)時(shí)開(kāi)通

自選配置、實(shí)時(shí)開(kāi)通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問(wèn)服務(wù)

1對(duì)1客戶咨詢顧問(wèn)

在線
客服

在線客服:7*24小時(shí)在線

客服
熱線

400-630-3752
7*24小時(shí)客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部