新的 PowerShell 7 ForEach-Object Parallel 是如何实现的?

How is the new PowerShell 7 ForEach-Object Parallel implemented?

PowerShell 7 为 运行 管道并行输入引入了一项急需的功能。

PowerShell 7 的文档没有提供有关如何实现的任何详细信息。

之前利用过 PoshRSJobInvoke-Parallel 模块,我知道运行空间传统上被认为是 powershell 中并行操作比 运行 PowerShell 作业更有效的方法。我读过一些混合内容,表明这是现在使用线程而不是运行空间,但找不到其他具体内容。

我非常感谢对以下方面的一些技术见解:

  1. 从 .NET 的角度来看,执行的生命周期是什么
  2. 新功能是运行空间还是线程? (或者运行空间只是 System.Management.Automation 中的一个 .NET 线程?)
  3. 既然我们正在转向并行操作,这是否会给传统调试带来任何复杂性? 从历史上看,我在使用运行空间进行调试时遇到了困难,并且不确定可以改进哪些选项

发现了这个很棒的博客 post PowerShell ForEach-Object Parallel Feature,作者是 Paul Higinbotham。

从这个博客post我摘取的主要亮点:

Script blocks run in a context called a PowerShell runspace. The runspace context contains all of the defined variables, functions and loaded modules.

As previously mentioned, the new ForEach-Object -Parallel feature uses existing PowerShell functionality to run script blocks concurrently....PowerShell itself imposes conditions on how scripts run concurrently, based on its design and history. Scripts have to run in runspace contexts and only one script thread can run at a time within a runspace. So in order to run multiple scripts simultaneously multiple runspaces must be created.

因此它确认运行空间是这方面的主要驱动因素,并提供了有关线程安全操作等的更多信息。关于运行空间的任何先前答案或详细信息都与此处相关,因为这是官方标准库中用于并行操作的运行空间的成熟实现。社区已经完成了面向运行空间的其他实现,但现在包含在没有外部模块依赖性的情况下。

感谢 Paul 为社区做出如此好的贡献!

正在调试 foreach-object -parallel:

我需要第二个 pwsh 进程来完成它。在第一个做:

foreach-object -parallel { Wait-Debugger;1;2;3 }

然后在第二个window中,弄清楚另一个pwsh的pid是多少。然后进入那个pshost进程。查看 运行 空间,并调试可用性为 "InBreakpoint" 的空间。 "v" 表示 "step over".

get-process pwsh

 NPM(K)    PM(M)      WS(M)     CPU(s)      Id  SI ProcessName
 ------    -----      -----     ------      --  -- -----------
     64    44.32      82.23       1.70    3912  12 pwsh
     63    40.66      78.03       1.36    6472  12 pwsh

$pid
6472

Enter-PSHostProcess 3912

get-runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Busy
  2 PSTask:1        localhost       Local         Opened        InBreakpoint
  3 RemoteHost      localhost       Local         Opened        Busy

debug-runspace 2
v
v
v

如果您 运行 foreach-object -parallel -asjob,您可以在同一个 window 中使用 get-运行space 和 debug-运行space。但是步进的时候看不到输出。

foreach-object -parallel { Wait-Debugger;1;2;3 } -asjob
get-runspace

 Id Name            ComputerName    Type          State         Availability
 -- ----            ------------    ----          -----         ------------
  1 Runspace1       localhost       Local         Opened        Available
  2 PSTask:1        localhost       Local         Opened        InBreakpoint

debug-runspace 2
v
v
v

这是一个新的调试视频,其中包含 Vscode 的一些高级设置:https://www.reddit.com/r/PowerShell/comments/gn0270/advanced_powershell_debugging_techniques/