【问题标题】:Running tasks parallel in powershell在 powershell 中并行运行任务
【发布时间】:2017-09-26 21:16:10
【问题描述】:

我有一个这样的 PowerShell 脚本:

Foreach ($file in $files) {
    [Do something]
    [Do something]
    [Do something]
}

这样一个文件一个接一个地处理。我想同时处理 4 个文件。

我知道 foreach -parallel 循环,但它会并行执行 [do something] 任务。我基本上想并行运行整个 foreach 循环。

如何在 PowerShell 中实现这一点?

【问题讨论】:

    标签: powershell foreach parallel-processing task


    【解决方案1】:

    您可以查看Jobsrunspaces。以下是 Jobs 的示例:

    $block = {
        Param([string] $file)
        "[Do something]"
    }
    #Remove all jobs
    Get-Job | Remove-Job
    $MaxThreads = 4
    #Start the jobs. Max 4 jobs running simultaneously.
    foreach($file in $files){
        While ($(Get-Job -state running).count -ge $MaxThreads){
            Start-Sleep -Milliseconds 3
        }
        Start-Job -Scriptblock $Block -ArgumentList $file
    }
    #Wait for all jobs to finish.
    While ($(Get-Job -State Running).count -gt 0){
        start-sleep 1
    }
    #Get information from each job.
    foreach($job in Get-Job){
        $info= Receive-Job -Id ($job.Id)
    }
    #Remove all jobs created.
    Get-Job | Remove-Job
    

    在上面的代码中,每个$file 都彼此并行运行(最多同时运行 4 个)。

    编辑:作为对 cme​​ts 的回应,here 是一些关于脚本块的文档。为什么必须包含参数的简短原因是因为与 PowerShell 函数不同,脚本块不能在大括号 {} 之外指定参数。

    【讨论】:

    • 做得很好,但我建议使用Wait-Job cmdlet 而不是您包含的所有花哨的逻辑来获取正在运行的作业并等待它们完成。 Link to alternative walk-through of runspaces that I personally learned it from and like.
    • 哦,你应该解释一下为什么必须将$file 参数传递到你的脚本块中。
    • 我会为以后的脚本研究这个。我不知道 Wait-Job 存在。
    • 这种使用作业的方法加载和过滤文件的速度要慢得多。我认为它会更快,因为可以同时加载和过滤 4 个文件。但实际上一个接一个地加载和过滤文件要快得多。你怎么解释这个?有没有办法让它更快?
    • 您愿意添加一个使用运行空间的示例吗?我正在阅读并尝试将您的工作示例转换为使用运行空间,但无法弄清楚。
    【解决方案2】:

    Powershell 7 引入foreach-object -parallel

    https://devblogs.microsoft.com/powershell/powershell-foreach-object-parallel-feature/

    然后你的脚本会说

    $files | ForEach-Object -parallel {
        [Do something]
        [Do something]
        [Do something]
    }
    

    【讨论】:

      【解决方案3】:

      根据Get-Help about_Foreach-ParallelForEach -Parallel... 将为每个项目并行处理整个脚本块,但脚本块中的命令将按顺序处理(尽管如果用Parallel {...} 括起来,它们可能会被并行化)。但是,您的脚本必须是 PowerShell 工作流程才能被接受; ParallelSequence 关键字仅在工作流中有效。

      【讨论】:

      • 来自 msdn.microsoft.com/en-us/powershell/reference/5.1/psworkflow/… :描述 Windows PowerShell 工作流中的 ForEach -Parallel 语言结构。如果您使用工作流,则 -Parallel 参数不存在。我没有感觉到 OP 正在处理工作流。
      • @tommymaynard - 是的,Parallel 开关和构造仅适用于工作流,我确实注意到了这一点。提问者在他的问题中确实提到了Foreach -parallel 构造,但似乎误解了效果,所以我假设工作流是一种可能性,并在此基础上回答。如果他不是,那么好奇一号给出的工作解决方案可能就是要走的路。
      • 你说得对,你确实提到了工作流程。很抱歉!
      猜你喜欢
      • 1970-01-01
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2020-06-21
      • 1970-01-01
      相关资源
      最近更新 更多