我正在使用PowerShell 3并使用Workflows,我遇到了一些奇怪的事情。 我正在使用 inlinescript 块来保存一些代码来表示我想要运行多个实例的任务。我发现可以跨并行实例访问在 inlinescript 块中声明的变量。
此处的示例具有并行进程休眠一个随机数毫秒,但您可以从控制台输出中看到多个并发进程可以睡眠相同的毫秒数。当然,这是可能的,但它经常是很明显,数据不是线程安全的。
workflow Invoke-ForEachParallel
{
param([string[]]$Computers)
foreach -parallel($PC in $Computers)
{
inlinescript {
"Executing on $using:PC"
[int]$i = get-random -min 200 -max 3000
"`t$using:PC - Sleeping for $i milliseconds."
start-sleep -Milliseconds $i
"`tFinished processing on $using:PC"
}
}
}
cls
Invoke-ForEachParallel (1..50)
所以,问题是:我怎样才能确保每个并发进程都使用自己的变量实例?
答案 0 :(得分:0)
David Wyatt在这个主题上简单而详细地回答了这两个问题。 http://social.technet.microsoft.com/Forums/scriptcenter/en-US/155b5638-5477-4e7c-a154-c6b56f6c3145/how-can-i-have-threadsafe-instance-variables-within-inlinescript-block-when-using-powershell?prof=required
简单回答: 当您使用inlineScript时,它不是一个多线程场景;这是多过程。 Workflow Foundation启动一个新的powershell.exe进程,每次都执行inlineScript块中的代码(您可以在运行脚本时在任务管理器中看到这种情况)。没有办法在不同的进程之间存在线程安全问题(除非您有正确的调试程序并且出于某些愚蠢的原因使用WriteProcessMemory)。
编辑:在我的Windows 7系统上,此脚本中生成的PowerShell.exe进程的数量似乎限制为5.我不确定WF是否会在每次执行inlineScript块时拆除并重新启动这些进程,或者,如果它将它们视为一个池,重复使用它们直到完成所有操作。出于性能原因,我会假设后者,但我没有阅读任何MS文档。