gpt4 book ai didi

powershell - 管道中的 cmdlet 是否并行执行?

转载 作者:行者123 更新时间:2023-12-04 17:30:41 25 4
gpt4 key购买 nike

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

enter image description here

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

最佳答案

这有点真实,但一点也不真实。

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

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

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



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

Cmdlet 及其构建 block

将 cmdlet 视为另一个函数可能很诱人,即在调用时同步执行的一组顺序语句。然而,这是不正确的。

在 PowerShell 中,cmdlet 是一个对象,它实现了至少 3 种方法之一:
  • BeginProcessing() - 运行一次,当管道开始执行
  • ProcessRecord() - 为收到的每个管道项目运行
  • EndProcessing() - 在处理完最后一个管道项后运行一次

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

    指出 cmdlet 在管道中同时执行可能更准确。

    让我们试试吧!

    由于上述三种方法直接映射到 begin , processend我们可以在高级函数中定义的 block ,很容易看到这个执行流程的效果。

    让我们尝试将 5 个对象提供给由三个 cmdlet 组成的管道,这些 cmdlet 使用 Write-Host 报告它们的状态看看会发生什么(见下面的代码):
    PS C:\> 1..5 |first |second |third |Out-Null

    pipeline processing

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

    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

    关于powershell - 管道中的 cmdlet 是否并行执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48522415/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com