Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
PowerShell 7.0'dan başlayarak, Foreach-Object cmdlet'indeki Parallel parametresi kullanılarak birden çok iş parçacığında aynı anda çalışma olanağı mümkündür. Ancak bu iş parçacıklarının ilerleme durumunu izlemek zor olabilir. Normalde, Yazma İlerlemesi'ni kullanarak bir işlemin ilerleme durumunu izleyebilirsiniz.
Bununla birlikte, PowerShell Paralel kullanırken her iş parçacığı için ayrı bir çalışma alanı kullandığından, ilerleme durumunu konağa geri raporlamak normal kullanımı Write-Progress
kadar düz değildir.
İlerleme durumunu izlemek için eşitlenmiş karma tablo kullanma
Birden çok iş parçacığından ilerlemeyi yazarken, PowerShell'de paralel işlemler çalıştırılırken her işlemin kendi çalışma alanı olduğundan izleme zorlaşır. Bu sorunu çözmek için eşitlenmiş bir karma tablo kullanabilirsiniz. Eşitlenmiş karma tablo, hata oluşturmadan aynı anda birden çok iş parçacığı tarafından değiştirilebilen iş parçacığı güvenli veri yapısıdır.
Ayarlama
Bu yaklaşımın dezavantajlarından biri, her şeyin hatasız çalıştığından emin olmak için biraz karmaşık bir kurulum yapmaktır.
$dataset = @(
@{
Id = 1
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 2
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 3
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 4
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 5
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
)
# Create a hashtable for process.
# Keys should be ID's of the processes
$origin = @{}
$dataset | Foreach-Object {$origin.($_.id) = @{}}
# Create synced hashtable
$sync = [System.Collections.Hashtable]::Synchronized($origin)
Bu bölüm, üç farklı amaçla üç farklı veri yapısı oluşturur.
değişkeni, $dataSet
değiştirilme riski olmadan sonraki adımları koordine etmek için kullanılan bir karma tablo dizisi depolar. Bir nesne koleksiyonu, koleksiyonda yinelenirken değiştirilirse PowerShell bir hata oluşturur. Döngüdeki nesne koleksiyonunu değiştirilmekte olan nesnelerden ayrı tutmalısınız. Id
Her karma tablodaki anahtar, sahte işlemin tanımlayıcısıdır. Anahtar, Wait
izlenen her sahte işlemin iş yükünün simülasyonunu oluşturur.
değişkeni, $origin
her anahtarın sahte işlem kimliklerinden biri olduğu iç içe yerleştirilmiş bir karma tablo depolar.
Ardından, değişkende depolanan eşitlenmiş karmatable'ı nemlendirmek $sync
için kullanılır. $sync
Değişken, ilerleme durumunu üst çalışma alanı olarak raporlamak ve ilerleme durumunu görüntülemekle sorumludur.
İşlemleri çalıştırma
Bu bölüm çok iş parçacıklı işlemleri çalıştırır ve ilerleme durumunu görüntülemek için kullanılan çıkışın bir kısmını oluşturur.
$job = $dataset | Foreach-Object -ThrottleLimit 3 -AsJob -Parallel {
$syncCopy = $using:sync
$process = $syncCopy.$($PSItem.Id)
$process.Id = $PSItem.Id
$process.Activity = "Id $($PSItem.Id) starting"
$process.Status = "Processing"
# Fake workload start up that takes x amount of time to complete
start-sleep -Milliseconds ($PSItem.wait*5)
# Process. update activity
$process.Activity = "Id $($PSItem.id) processing"
foreach ($percent in 1..100)
{
# Update process on status
$process.Status = "Handling $percent/100"
$process.PercentComplete = (($percent / 100) * 100)
# Fake workload that takes x amount of time to complete
Start-Sleep -Milliseconds $PSItem.Wait
}
# Mark process as completed
$process.Completed = $true
}
Sahte işlemler iş Foreach-Object
olarak gönderilir ve başlatılır. Bir kuyrukta birden çok işlemin çalıştırılmasını vurgulamak için ThrottleLimit 3 olarak ayarlanır. İşler değişkeninde $job
depolanır ve daha sonra tüm işlemlerin ne zaman tamamlandığını bilmemize olanak tanır.
PowerShell'de using:
üst kapsam değişkenine başvurmak için deyimini kullanırken, bunu dinamik hale getirmek için ifadeleri kullanamazsınız. Örneğin, gibi bir değişken oluşturmaya $process
çalışırsanız, $process = $using:sync.$($PSItem.id)
burada ifadeleri kullanamadığını belirten bir hatayla karşılaşırsınız. Bu nedenle, değişkene $syncCopy
başvurmak ve değişkenini başarısız olma riski olmadan değiştirebilmek $sync
için değişkeni oluştururuz.
Ardından, eşitlenmiş karma tablo anahtarlarına başvurarak değişkenini kullanarak $process
döngüde olan işlemin ilerleme durumunu temsil eden bir karma tablo oluşturacağız. Activity ve Status anahtarları, sonraki bölümde belirli bir sahte işlemin durumunu görüntülemek için Write-Progress
parametresi değerleri olarak kullanılır.
Döngüforeach
, işlemin çalışmasının benzetimini yapmak için kullanılan bir yöntemdir ve milisaniyeler kullanılarak ayarlamak Start-Sleep
için Wait özniteliğine göre $dataSet
rastgele oluşturulur. İşleminizin ilerleme durumunu hesaplama şekliniz farklılık gösterebilir.
Birden çok işlemin ilerleme durumunu görüntüleme
Artık sahte işlemler iş olarak çalıştığına göre, işlemlerin ilerleme durumunu PowerShell penceresine yazmaya başlayabiliriz.
while($job.State -eq 'Running')
{
$sync.Keys | Foreach-Object {
# If key is not defined, ignore
if(![string]::IsNullOrEmpty($sync.$_.keys))
{
# Create parameter hashtable to splat
$param = $sync.$_
# Execute Write-Progress
Write-Progress @param
}
}
# Wait to refresh to not overload gui
Start-Sleep -Seconds 0.1
}
$job
değişkeni üst işi içerir ve sahte işlemlerin her biri için bir alt işe sahiptir. Alt işlerden herhangi biri çalışmaya devam ederken, üst iş Durumu "Çalışıyor" olarak kalır. Bu, tüm işlemler tamamlanana kadar her işlemin ilerleme durumunu sürekli olarak güncelleştirmek için döngüsünü kullanmamıza while
olanak tanır.
while döngüsü içinde değişkendeki $sync
anahtarların her biri arasında döngü yapıyoruz. Bu eşitlenmiş bir karma tablo olduğundan, sürekli olarak güncelleştirilir, ancak herhangi bir hata oluşturmadan yine erişilebilir.
Bildirilen işlemin yöntemini kullanarak IsNullOrEmpty()
gerçekten çalıştığından emin olmak için bir denetim vardır. İşlem başlatılmadıysa, döngü üzerinde rapor vermez ve başlatılan bir işleme gelene kadar sonrakine geçer. İşlem başlatılırsa, parametreleri Write-Progress
'ye eklemek için geçerli anahtardan karma tablo kullanılır.
Tam örnek
# Example workload
$dataset = @(
@{
Id = 1
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 2
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 3
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 4
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
@{
Id = 5
Wait = 3..10 | get-random | Foreach-Object {$_*100}
}
)
# Create a hashtable for process.
# Keys should be ID's of the processes
$origin = @{}
$dataset | Foreach-Object {$origin.($_.id) = @{}}
# Create synced hashtable
$sync = [System.Collections.Hashtable]::Synchronized($origin)
$job = $dataset | Foreach-Object -ThrottleLimit 3 -AsJob -Parallel {
$syncCopy = $using:sync
$process = $syncCopy.$($PSItem.Id)
$process.Id = $PSItem.Id
$process.Activity = "Id $($PSItem.Id) starting"
$process.Status = "Processing"
# Fake workload start up that takes x amount of time to complete
start-sleep -Milliseconds ($PSItem.wait*5)
# Process. update activity
$process.Activity = "Id $($PSItem.id) processing"
foreach ($percent in 1..100)
{
# Update process on status
$process.Status = "Handling $percent/100"
$process.PercentComplete = (($percent / 100) * 100)
# Fake workload that takes x amount of time to complete
Start-Sleep -Milliseconds $PSItem.Wait
}
# Mark process as completed
$process.Completed = $true
}
while($job.State -eq 'Running')
{
$sync.Keys | Foreach-Object {
# If key is not defined, ignore
if(![string]::IsNullOrEmpty($sync.$_.keys))
{
# Create parameter hashtable to splat
$param = $sync.$_
# Execute Write-Progress
Write-Progress @param
}
}
# Wait to refresh to not overload gui
Start-Sleep -Seconds 0.1
}
İlişkili Bağlantılar
PowerShell