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

前端之家收集整理的这篇文章主要介绍了powershell – 管道中的cmdlet是并行执行的吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在“专业人士的Power Shell笔记”白皮书中发现了一个有趣的声明 – “在管道系列中,每个函数都与其他函数并行运行,如并行线程”:

enter image description here

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

解决方法

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

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

If a command writes a single object,its successor receives that@H_502_25@ object and then terminates after writing its own object(s) to its@H_502_25@ successor. If,however,a command writes multiple objects,they are@H_502_25@ delivered one at a time to the successor command,which executes once@H_502_25@ per object. This behavior is called streaming. In stream processing,@H_502_25@objects are written along the pipeline as soon as they become@H_502_25@ available,not when the entire collection has been produced.

When processing a collection,a command can be written such that it@H_502_25@ can do special processing before the initial element and after the@H_502_25@ final element.

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

Cmdlet及其构建块

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

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

> BeginProcessing() – 当管道开始执行时运行一次@H_502_25@> ProcessRecord() – 为收到的每个管道项目运行@H_502_25@> EndProcessing() – 在处理完最后一个管道项后运行一次

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

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

我们来试试吧!

由于上述三种方法直接映射到我们可以在高级函数中定义的begin,process和end块,因此很容易看到此执行流程的效果.

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

PS C:\> 1..10 |first |second |third |Out-Null

pipeline processing

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

pipeline buffering

希望这有一定道理!

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

以下函数的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

猜你在找的设计模式相关文章