问题
When using Powershell Jobs, Runspaces, or Workflows, are the threads being executed on separate cores? (and if so, how do we tell powershell how many cores to use? -- sorry that's 2 questions.)
.Net has the Task Parallel Library, which allows a 'for loop' to run in parallel, using all available cores (here is one example). Does Powershell Jobs, Runspaces, or Workflows do something similar? And by similar, I mean are the threads actually running on separate cores, in parallel?
I found a similar question here, but it seems unclear (to me anyway) if the threads are executed on separate cores. It seems that sometimes multi-threads are mistaken for parallel, as mentioned here.
If using multiple cores with Powershell is not possible, I will use C# or perhaps Python, but my first choice is to use Powershell because (insert long list of reasons).
If it's relevant, I'm trying to do all this to help a co-worker who does server admin type stuff. Currently, his powershell script loops through a list of servers, and foreach server, does stuff. Currently the script runs on an 8 core machine, but is only using one core. I'm sure there are other ways to boost performance, but doing it in parallel is my current goal.
回答1:
I would say yes if by separate cores, you mean logical cores (not physical cores). Run something like this and notice the output from “$num”. $num represents the current logical (not physical) core on which a thread is running. If this script runs on a dual core machine (with 4 logical cores), the output of $num is a 0, 1, 2, or 3. See here for a better explanation on Logical vs Physical CPU.
$sb = {
param($sbarg)
$MethodDefinition = @'
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
public static extern int GetCurrentProcessorNumber();
'@
$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -Namespace 'Win32' -PassThru
0..10 | % {
$num = $Kernel32::GetCurrentProcessorNumber()
Write-Output "[$sbarg]:[$_] on '$num'"
# simulate some work that may make the cpu busy
# perhaps watch in task manager as well to see load
$result = 1; foreach ($number in 1..1000000) {$result = $result * $number};
Start-Sleep -Milliseconds 500
}
}
0..10 | % {
Start-Job -ScriptBlock $sb -ArgumentList $_
}
Get-Job
# Wait for it all to complete
While (Get-Job -State "Running")
{
Write-Output "waiting..."
Start-Sleep 2
}
# Getting the information back from the jobs
Get-Job | Receive-Job
# Clean Up
Get-Job | Remove-Job
来源:https://stackoverflow.com/questions/53331116/when-using-powershell-jobs-runspaces-or-workflows-are-the-threads-being-execu