powershell的并行foreach最多使用5个线程吗?

时间:2017-04-27 01:18:58

标签: powershell parallel-for

throttlelimit的{​​{1}}参数可以控制执行脚本时使用的进程数。但即使我将foreach -parallel设置为大于5,我也不能超过5个。

脚本在多个PowerShell进程中执行。所以我在脚本中检查PID。然后对PID进行分组,以便我可以知道有多少进程用于执行脚本。

throttlelimit

输出

function GetPID() {
    $PID
}

workflow TestWorkflow {
    param($throttlelimit)
    foreach -parallel -throttlelimit $throttlelimit ($i in 1..100) {
        GetPID
    }
}

foreach ($i in 1..8) {
    $pids = TestWorkflow -throttlelimit $i
    $measure = $pids | group | Measure-Object
    $measure.Count
}

对于1 2 3 4 5 5 5 5 小于或等于5,我有$i个进程。但是对于大于5的$i,我只有5个进程。有没有办法在执行脚本时增加进程数?

编辑:为了回应@ SomeShinyObject的回答,我添加了另一个测试用例。它是对@SomeShinyObject给出的示例的修改。我添加了一个函数$i,它只能睡10秒钟。

S

这是输出。我按时间(秒数)对输出进行分组,并在每个组中进行一些重新排序以使其更清晰。很明显,函数function S($n) { $s = Get-Date $s.ToString("HH:mm:ss.ffff") + " start sleep " + $n sleep 10 $e = Get-Date $e.ToString("HH:mm:ss.ffff") + " end sleep " + $n + " diff " + (($e-$s).TotalMilliseconds) } Workflow Throttle-Me { [cmdletbinding()] param ( [int]$ThrottleLimit = 10, [int]$CollectionLimit = 10 ) foreach -parallel -throttlelimit $ThrottleLimit ($n in 1..$CollectionLimit){ $s = Get-Date $s.ToString("HH:mm:ss.ffff") + " start " + $n S $n $e = Get-Date $e.ToString("HH:mm:ss.ffff") + " end " + $n + " diff " + (($e-$s).TotalMilliseconds) } } Throttle-Me -ThrottleLimit 10 -CollectionLimit 20 被称为5乘5,虽然我将S设置为10(首先我们有throttlelimit,10秒后,我们有start sleep 6..10和10秒后start sleep 1..5,以及10秒后start sleep 11..15)。

start sleep 16..20

2 个答案:

答案 0 :(得分:1)

我相信你的测试有点缺陷。根据此TechNet article$PID不是脚本工作流中的可用变量。

可以在site

上找到更好的解释和解释

基本上,ThrottleLimit设置为理论[Int32]::MaxValue。海报设计了一个更好的测试,以检查并行处理(略有修改):

Workflow Throttle-Me {
    [cmdletbinding()]
    param (
        [int]$ThrottleLimit = 10,
        [int]$CollectionLimit = 10
    )

    foreach -parallel -throttlelimit $ThrottleLimit ($n in 1..$CollectionLimit){
        "Working on $n"
        "{0:hh}:{0:mm}:{0:ss}" -f (Get-Date)
    }
}

答案 1 :(得分:0)

我不能代表那个特定的cmdlet,但是你发现PowerShell每个PID只使用一个线程。解决此问题的常见方法是PSJobsRunspaces。 Runspaces比PSJobs更难,但它们也有更好的性能,这使它们成为流行的选择。缺点是你的整个代码必须解决它们,这意味着在大多数情况下整个重写。

不幸的是,就像微软推动PowerShell一样,它并不是为了提高性能和速度。但它与.NET相关的确如此好。