Board logo

标题: [转载代码] [PowerShell每日技巧]并行处理(20140411) [打印本页]

作者: DAIC    时间: 2014-4-15 17:22     标题: [PowerShell每日技巧]并行处理(20140411)

If a script needs some speed-up, you might find background jobs helpful. They can be used if a script does a number of things that also could run concurrently.

PowerShell is single-threaded and can only do one thing at a time. With background jobs, additional PowerShell processes run in the background and can share the workload. This works well only if the jobs you need to do are completely independent from each other, and if your background job does not need to produce a lot of data. Sending back data from a background job is an expensive procedure that can easily eat up all the saved time, resulting in an even slower script.

Here are three tasks that all can run concurrently:
  1. $start = Get-Date
  2. # get all hotfixes
  3. $task1 = { Get-Hotfix }
  4. # get all scripts in your profile
  5. $task2 = { Get-Service | Where-Object Status -eq Running }
  6. # parse log file
  7. $task3 = { Get-Content -Path $env:windir\windowsupdate.log | Where-Object { $_ -like '*successfully installed*' } }
  8. # run 2 tasks in the background, and 1 in the foreground task
  9. $job1 =  Start-Job -ScriptBlock $task1
  10. $job2 =  Start-Job -ScriptBlock $task2
  11. $result3 = Invoke-Command -ScriptBlock $task3
  12. # wait for the remaining tasks to complete (if not done yet)
  13. $null = Wait-Job -Job $job1, $job2
  14. # now they are done, get the results
  15. $result1 = Receive-Job -Job $job1
  16. $result2 = Receive-Job -Job $job2
  17. # discard the jobs
  18. Remove-Job -Job $job1, $job2
  19. $end = Get-Date
  20. Write-Host -ForegroundColor Red ($end - $start).TotalSeconds
复制代码
On a sample system, executing all three tasks took 5.9 seconds. The results for all three tasks are available in $result1, $result2, and $result3.

Let's check how long it takes for all three tasks to run consecutively in the foreground.
  1. $start = Get-Date
  2. # get all hotfixes
  3. $task1 = { Get-Hotfix }
  4. # get all scripts in your profile
  5. $task2 = { Get-Service | Where-Object Status -eq Running }
  6. # parse log file
  7. $task3 = { Get-Content -Path $env:windir\windowsupdate.log | Where-Object { $_ -like '*successfully installed*' } }
  8. # run them all in the foreground:
  9. $result1 = Invoke-Command -ScriptBlock $task1
  10. $result2 = Invoke-Command -ScriptBlock $task2
  11. $result3 = Invoke-Command -ScriptBlock $task3
  12. $end = Get-Date
  13. Write-Host -ForegroundColor Red ($end - $start).TotalSeconds
复制代码
As it turns out, this time it only took 5.05 seconds. So background jobs really pay off for long running tasks that all take almost the same time. Since the three sample tasks returned a lot of data, the benefit of executing them concurrently was eliminated by the overhead that it took to serialize the return data and transport it back to the foreground process.

http://powershell.com/cs/blogs/tips/archive/2014/04/11/parallel-processing-in-powershell.aspx




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2