0

我正在使用 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)

所以,问题是:我怎样才能确保每个并发进程都在使用自己的变量实例?

4

1 回答 1

1

大卫怀亚特在这个线程上既简单又详细地回答了。 http://social.technet.microsoft.com/Forums/scriptcenter/en-US/155b5638-5477-4e7c-a154-c6b56f6c3145/how-can-i-have-threadsafe-instance-variables-within-inlinescript-block-何时使用 powershell?prof=required

简单的回答:当你使用 inlineScript 时,它不是一个多线程的场景;它是多进程的。Workflow Foundation 每次都会启动一个新的 powershell.exe 进程来执行 inlineScript 块中的代码(您可以在运行脚本时在任务管理器中看到这种情况)。单独的进程之间不可能存在线程安全问题(除非您拥有正确的调试程序并出于某种愚蠢的原因使用 WriteProcessMemory)。

编辑:在我的 Windows 7 系统上,此脚本中生成的 PowerShell.exe 进程的数量似乎限制为 5。我不确定 WF 是否会在每次执行 inlineScript 块时拆除并重新启动这些进程,或者是否它将它们视为一个池,重复使用它们直到一切都完成。出于性能原因,我会假设后者,但我没有阅读任何关于此效果的 MS 文档。

于 2013-07-29T19:48:57.267 回答