使用RunspacePool显示顺序输出

时间:2015-11-03 16:49:38

标签: multithreading powershell

我在Powershell中发现并行计算,但有些东西我无法获得。即使我使用RunspacePool,我的任务输出也会按顺序显示。请使用以下代码:

Param(
    [int]$MaxJobs = 3
)


Begin {
    $Jobs = @()
    $JobQueue = [System.Collections.Queue]::Synchronized(
        (New-Object System.Collections.Queue)
    )

    if ($MaxJobs -lt 0) {
        $MaxJobs = 1
    }
    if ($MaxJobs -eq 0) {
        $MaxJobs = 50
    }

    $JobPool = [RunspaceFactory]::CreateRunspacePool(1, $MaxJobs)
    $JobPool.Open()
}


Process {
    for ($i = 0; $i -lt 50; $i++)
    {
        $script = '$t = Get-Random -Minimum 1 -Maximum 10; "' + $i + ': $t" | Out-File jobs.out -Append; sleep $t;'

        $thread = [powershell]::Create()
        $thread.AddScript($script) | Out-Null
        $thread.RunspacePool = $JobPool
        $handle = $thread.BeginInvoke()

        $j = "" | Select-Object Handle, Thread
        $j.Handle = $handle
        $j.Thread = $thread
        $Jobs += $j
    }
}


End {
    while (@($Jobs | Where-Object {$_.Handle -ne $Null}).Count -gt 0) {
        foreach ($j in $($Jobs | Where-Object {$_.Handle.IsCompleted -eq $True})) {
            $j.Thread.EndInvoke($j.Handle)
            $j.Thread.Dispose()
            $j.Thread = $Null
            $j.Handle = $Null
        }
    }
    $JobPool.Close() | Out-Null
    $JobPool.Dispose() | Out-Null
}

Process块中,给定随机休眠值,我希望文件也可以随机写入,但事实并非如此。

 0 :   7 
 1 :   1  
 2 :   1  
 3 :   8  
 4 :   8  
 5 :   2  
 6 :   7  
 7 :   9  
 8 :   9  
 9 :   9  
 1 0 :   3
 1 1 :   3
 1 2 :   5
 1 3 :   5
 1 4 :   3
 1 5 :   1
 1 6 :   1
 1 7 :   9
 1 8 :   9
 1 9 :   1
 2 0 :   8
 2 1 :   1
 2 2 :   1
 2 3 :   1
 2 4 :   1
 2 5 :   1
 2 6 :   1
 2 7 :   8
 2 8 :   8
 2 9 :   9
 3 0 :   8
 3 1 :   8
 3 2 :   1
 3 3 :   6
 3 4 :   1
 3 5 :   1
 3 6 :   5
 3 7 :   5
 3 8 :   5
 3 9 :   9
 4 0 :   3
 4 1 :   3
 4 2 :   5
 4 3 :   5
 4 4 :   4
 4 5 :   4
 4 6 :   4
 4 7 :   1
 4 8 :   1
 4 9 :   4

这是正常行为吗?

1 个答案:

答案 0 :(得分:2)

仔细查看您在运行空间池中运行的语句:

$script = '$t = Get-Random -Minimum 1 -Maximum 10; "' + $i + ': $t" | Out-File jobs.out -Append; sleep $t;'

或格式很好:

$t = Get-Random -Minimum 1 -Maximum 10
"$i: $t" | Out-File jobs.out -Append
Sleep $t

您在睡眠之前写入文件,因此Start-Sleep命令的持续时间当然不会影响写入文件的顺序。

如果您想查看睡眠的效果,请将Out-File语句放在最后:

$script = '$t = Get-Random -Minimum 1 -Maximum 10; sleep $t;"' + $i + ': $t" | Out-File jobs.out -Append;'