Univerzális párhuzamosító függvény

Az előzőekből kiindulva készítsünk egy olyan függvényt, ami egy univerzális, párhuzamosan végrehajtó ForeEach‑Object, legyen a neve Invoke-MultiThread:

function Invoke-MultiThread {

param(

     $script,

     $maxthread = 5,

     [switch] $verbose

)

 

begin {

     $rp = [runspacefactory]::CreateRunspacePool(1, $maxthread)

     $rp.Open()

     $jobs = New-Object System.Collections.ArrayList

     $start = get-date

 

     function Get-Results {

          param([switch]$wait)

          do {

                $ActiveThreads = 0

                $wasoutput = $false

                $hasdata = $false

                foreach($job in $jobs) {

                      if ($job.job.isCompleted) {

                            $job.thread.EndInvoke($job.job)

                            $wasoutput = $true

                            $job.thread.dispose()

                            $job.job = $null

                            $job.thread = $null

                      }

                      elseif ($job.job -ne $null) {

                            $ActiveThreads++

                            $hasdata = $true

                      }

                }

                if($verbose -and $wait -and $wasoutput){

                      $elapsed = "{0:n2}" -f ((get-date) - $start).totalseconds

                      Write-host "$elapsed sec - Active threads: $activethreads" -ForegroundColor green

                }

                if ($hasdata -and $wait) {

                      Start-Sleep -Milliseconds 500

                }

          } while ($hasdata -and $wait)

     }

}

process{

     $p = [powershell]::Create().AddScript($ScriptBlock).AddArgument($_)

     $p.RunspacePool = $rp

     $rv = New-Object -TypeName PSObject -Property @{

                Thread = $p

                Job = $p.BeginInvoke()

          }

     [void]$jobs.Add($rv)

     Get-Results

}

end{

     Get-Results -wait

     $rp.Close()

}

}

Nagyjából megtisztítottam minden sallangtól a belsejét, egy kicsit átalakított –verbose üzemmódot hagytam csak benne. Nézzük, hogyan fut:

[6] PS C:\> 1..5 | %{New-Object -TypeName PSObject -Property @{Hossz = 1; ID =

$_}} | Invoke-MultiThread -script $ScriptBlock -maxthread 2 -verbose

        Kész 1 : 1 sec

        Kész 2 : 1 sec

1,08 sec - Active threads: 3

        Kész 3 : 1 sec

        Kész 4 : 1 sec

2,12 sec - Active threads: 1

        Kész 5 : 1 sec

3,15 sec - Active threads: 0

A 2 párhuzamos szálnál 5 elem iterálásához 3 menetre volt szükség. Nézzük, mi van, ha növeljük a párhuzamos szálak számát:

[7] PS C:\> 1..5 | %{New-Object -TypeName PSObject -Property @{Hossz = 1; ID =

$_}} | Invoke-MultiThread -script $ScriptBlock -maxthread 5 -verbose

        Kész 1 : 1 sec

        Kész 2 : 1 sec

        Kész 3 : 1 sec

        Kész 4 : 1 sec

        Kész 5 : 1 sec

1,14 sec - Active threads: 0

Láthatóan egyszerre elvégzett minden feladatot.

Tovább is lehetne ezt még fejleszteni, hogy a szálak számának beállításához vegye figyelembe a mindenkori processzor és memória igénybe vételt, és a szálak számát úgy hangolja, hogy a gép ne terhelje halálra magát.



Word To HTML Converter