管道中的cmdlet是并行执行的吗?

iPa*_*h ツ 5 parallel-processing powershell pipeline

我在"专业人士的PowerShell笔记"白皮书中发现了一个有趣的声明 - "在管道系列中,每个函数都与其他函数并行运行,如并行线程":

在此输入图像描述

那是对的吗?如果"是",是否有支持此声明的技术文档?

Mat*_*sen 9

这有点真实,但根本不是.

我的意思是什么?首先,让我们解决您的文档问题.以下内容来自PowerShell 3.0版语言规范的第3.13段:

如果命令写入单个对象,则其后继接收该对象,然后在将其自己的对象写入其后继对象后终止.但是,如果命令写入多个对象,则它们会一次一个地传递给后继命令,后者每个对象执行一次.此行为称为流式传输.在流处理中, 对象一旦可用就沿管道写入,而不是在生成整个集合时写入.

处理集合时,可以编写一个命令,使其可以在初始元素之前和最终元素之后进行特殊处理.

现在,让我们简要了解一下cmdlet的组成.


Cmdlet及其构建块

将cmdlet视为另一个函数,即每次调用时要同步执行的一组连续语句,这可能很诱人.然而,这是不正确的.

PowerShell中的cmdlet是一个实现至少3种方法之一的对象:

管道开始执行后,BeginProcessing()将在管道中的每个cmdlet上调用.从这个意义上说,管道中的所有cmdlet都是"并行"运行的 - 但是这种设计基本上允许我们用单个线程执行管道 - 因此不需要按照设计执行管道的涉及多个线程的实际并行处理.

可能更准确地指出cmdlet 在管道中并发执行.


我们来试试吧!

由于三个以上方法直接映射到begin,processend块,我们可以在一个先进的功能定义,可以很容易地看到这个执行流程的效果.

让我们尝试将10个对象提供给由三个cmdlet组成的管道,报告其状态Write-Host并查看会发生什么(请参阅下面的代码):

PS C:\> 1..5 |first |second |third |Out-Null
Run Code Online (Sandbox Code Playgroud)

管道处理

请注意,PowerShell通过-OutBuffercommon参数支持外部输出缓冲控制,这也将影响执行流程:

管道缓冲

希望这有一定道理!


这是我为上面的演示编写的代码.

Write-Host以下函数的输出将根据我们使用的别名更改其颜色,因此在shell中更容易区分.

function Test-Pipeline {
  param(
    [Parameter(ValueFromPipeline)]
    [psobject[]]$InputObject
  )

  begin {
    $WHSplat = @{
      ForegroundColor = switch($MyInvocation.InvocationName){
        'first' {
          'Green'
        }
        'second' {
          'Yellow'
        }
        'third' {
          'Red'
        }
      }
    }
    Write-Host "Begin $($MyInvocation.InvocationName)" @WHSplat
    $ObjectCount = 0
  }

  process {
    foreach($Object in $InputObject) {
      $ObjectCount += 1
      Write-Host "Processing object #$($ObjectCount) in $($MyInvocation.InvocationName)" @WHSplat
      Write-Output $Object
    }
  }

  end {
    Write-Host "End $($MyInvocation.InvocationName)" @WHSplat
  }

}

Set-Alias -Name first  -Value Test-Pipeline
Set-Alias -Name second -Value Test-Pipeline
Set-Alias -Name third  -Value Test-Pipeline
Run Code Online (Sandbox Code Playgroud)

  • 简而言之,PowerShell cmdlet可以并发运行(但不必并行运行)。当然,直到21世纪初,计算机上的“一切”都是如此,但是只有软件工程师才会费心去区分;-) https://softwareengineering.stackexchange.com/a/190725/29348 (3认同)
  • @iPathツ 正确理解,是的:-) (2认同)