• 10月26日十九大新闻发言人专题新闻发布会 2019-03-22
  • 多交140分“亚裔税”?哈佛大学被控歧视亚裔学生 2019-03-22
  • 男子农田挖到古董抠出吓得魂飞魄散 2019-03-17
  • 瑞典南部城市发生枪击案致5人伤 警方:与恐袭无关 2019-03-10
  • 西安幼升小入学难问题出在哪儿教育部门将统筹协调安排 2019-03-10
  • 传统强队集体慢热(世界杯纵横) 2019-03-10
  • 乌鲁木齐水磨沟区开建两座立体停车库 2019-03-10
  • 山西新闻网特约摄影师名单&山西视觉志 2019-02-05
  • 广州旅游为何爆发出强大且持续的吸引力 2019-02-05
  • 今天看啥
      热点:

        北京赛车pk10历史记录 www.zwahn.com

        PowerShell中Job相关命令及并行执行任务详解,powershell任务详解


        前言

        在 PowerShell 中可以轻松的执行后台任务并且让多个后台任务并行执行。本文介绍 PowerShell 中 Job 相关的一些命令,并通过 demo 演示如何在后台同时执行多个任务。下面话不多说了,来一起看看详细的介绍吧。

        PowerShell 中执行后台任务的模式

        下图描述了在 PowerShell 中执行后台任务的进程模型(此图来自互联网):

        首先我们需要一个 PowerShell 进程执行与用户交互的命令,比如执行 Start-Job 命令运行一个后台任务。每一个这样的后台任务都会在一个新启动的 PowerShell 进程中执行。所以,如果我们同时启动三个后台任务,那么一共有四个 PowerShell 进程在同时运行。

        Job 相关的命令

        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 { sleep 5 }

        启动单个任务并等待任务结束

        多数情况下我们是需要知道任务的结束时间的,此时可以通过 Wait-Job 命令阻塞执行流程,直到等待的任务结束:

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

        注意:上面的内容是由 Wait-Job 命令输出的,当时任务的状态为 "Completed"。

        更进一步,我们还想要获得任务执行过程中的输出。这时我们就需要用到 Receive-Job 命令。你可以在任务启动后的任何时刻执行 Receive-Job 命令,但是如果想要得到完整的输出,就需要在任务结束后调用,此时需要配合 Wait-Job 命令一起使用:

        $job = Start-Job -ScriptBlock { sleep 5; Write-Host "Hello world."; }
        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 { 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 + " 已经完成")
           Receive-Job $job
           $taskCount--
           Remove-Job $job
          }
         }
         sleep 1
        }
        "所有任务已完成" 
        #得出任务运行的时间
        (New-TimeSpan $start_time).totalseconds

        把上面的代码保存到 mytask.ps1 文件中并执行:

        代码中我们给每个任务起了名字,并在 while 循环中不断的使用 Get-Job 命令检查任务当前的状态,如果发现任务的状态为 "Completed",就通过 Remove-Job 命令删除它,并在删除前打印任务的名称和 output。

        封装一个执行后台任务的函数

        下面我们用封装一个简单的函数来并行执行多个任务:

        function Run-Tasks
        {
         Param
         (
          $taskArr,
          $parallelcount=1
         )
         #测试计时开始
         $startTime = (Get-Date)
          #移除本次会话中已有的所有后台任务
         Remove-Job *
         # 使用变量 $taskCount 保存还没有执行完成的任务数
         $taskCount = $taskArr.Length
         
         #判断设定的并行任务数是否超过当前任务队列中的任务数
         if($parallelCount -gt $taskArr.Length)
         {
          $parallelCount = $taskArr.Length
         }
         #启动初始任务
         foreach($i in 1..$parallelCount)
         {
          Start-Job $taskArr[$i - 1] -Name "task$i"
         }
         #初始任务完成后开始的任务
         $nextIndex = $parallelCount
         #当任务队列中还有任务时不断轮询已建立的任务,当一个后台任务结束时删除这个任务,
         #然后从任务队列中取出下一个任务进行执行,然后等待所有任务执行完成。
         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 + " 已经完成,结果如下:")
            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
         }
         "所有任务已完成"
         #得出任务运行的时间
         (New-TimeSpan $startTime).totalseconds
        }

        上面的函数会在后台执行用户的任务,然后等待所有的任务执行结束。并且用户可以指定同时执行的任务的个数,在任务执行完成后,输出任务的 output。接下来让我们尝试使用这个函数执行一些任务:

        #定义 6 个任务
        $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 个任务写入到一个数组中作为任务队列
        $taskArr = $task1, $task2, $task3, $task4, $task5, $task6
        #运行数组中的任务,允许同时运行 4 个任务
        Run-Tasks -taskArr $taskArr -parallelcount 4

        下面是运行的结果:

        总结

        能够随心所欲的在后台执行任务是一件感觉非常棒的事情!当然,对于工作来说你能够把事情做得又快又好(又好可不敢说)。本文只是提供了一个简单的运行并行任务的 demo,省略了异常处理等重要内容,但这已经足够您开始 PowerShell 并行任务之旅了。

        参考:

        《Windows PowerShell 实战第二版》
        Powershell:简单实现并行任务的脚本

        北京赛车pk10历史记录 www.zwahn.comtrue//www.zwahn.com/jcjc/1314433.htmlTechArticlePowerShell中Job相关命令及并行执行任务详解,powershell任务详解 前言 在 PowerShell 中可以轻松的执行后台任务并且让多个后台任务并行执行。本...

        相关文章

        相关搜索: powershell 并行 job

        帮客评论

        视觉看点
      • 10月26日十九大新闻发言人专题新闻发布会 2019-03-22
      • 多交140分“亚裔税”?哈佛大学被控歧视亚裔学生 2019-03-22
      • 男子农田挖到古董抠出吓得魂飞魄散 2019-03-17
      • 瑞典南部城市发生枪击案致5人伤 警方:与恐袭无关 2019-03-10
      • 西安幼升小入学难问题出在哪儿教育部门将统筹协调安排 2019-03-10
      • 传统强队集体慢热(世界杯纵横) 2019-03-10
      • 乌鲁木齐水磨沟区开建两座立体停车库 2019-03-10
      • 山西新闻网特约摄影师名单&山西视觉志 2019-02-05
      • 广州旅游为何爆发出强大且持续的吸引力 2019-02-05