Я пытаюсь добавить значение в глобальный массив внутри функции. Вызов функции является многопоточным, и несколько экземпляров функции вызываются мгновенно.
Каждый поток изменяет массив, но перезаписывает данные, записанные в него другими потоками.
Мой код ниже:
Function QuickPing {
param ($LastByte)
$P = New-Object -TypeName "System.Net.NetworkInformation.Ping"
if (($P.Send("200.200.200.$LastByte")).status -eq "success"){
echo "this one responded 200.200.200.$LastByte"
$global:alive+ = "200.200.200.$LastByte"
$global:alive
}
}
$global:alive = @()
1..255 | Start-Parallel -Command QuickPing -MaxThreads 500
write-host $alive
и результат ниже:
PS C:\WINDOWS\system32> E:\scripts_during_phase2\ping_array.ps1
this one responded 200.200.200.1
200.200.200.1
this one responded 200.200.200.17
200.200.200.17
this one responded 200.200.200.254
200.200.200.254
PS C:\WINDOWS\system32> $alive
PS C:\WINDOWS\system32>
Как видно выше, значение в массиве $ alive перезаписывается каждый раз при вызове этой функции.
Как убедиться, что $alive
содержит 200.200.200.1,200.200.200.17,200.200.200.254
при запуске команды write-host $alive
Используйте замок.
https://en.wikipedia.org/wiki/Lock_(computer_science)
Это гарантирует, что только один поток будет иметь доступ к массиву одновременно.
А как поделить состояние замка? Это в основном решение Словить 22, если вы не уточните, как это реализовать для этого вопроса.
Start-Parallel
кажется настраиваемым модулем, основанным наRunspaceFactory Class
. На самом деле есть явное примечание из дизайна*Remember that RunSpaces don’t share anything*
, что в целом не верно для RunSpaces, поскольку вы можете обмениваться информацией сSessionStateProxy Class
, но это, по-видимому, не реализовано в этом решении.