如何并行运行PowerShell管道进程?

时间:2020-09-07 17:01:30

标签: powershell pipeline

在PowerShell管道中运行进程时,下一个进程仅在前一个进程退出后才开始。这是一个演示的简单命令:

python -c "from time import *; print(time()); sleep(3)" | python -c "from time import *; print(input()); print(time())"

将打印以下内容:

1599497759.5275168
1599497762.5317411

(请注意,时间间隔为3秒)。

有什么办法可以使进程并行运行?寻找可在Windows PowerShell或Windows PowerShell上运行的解决方案。

我发现了this question,但是它只处理cmdlet,而不处理普通的可执行文件。

3 个答案:

答案 0 :(得分:1)

这很可能是PowerShell的本机命令处理器在将其绑定到下游命令之前,正在等待看是否还有其他输出。

显式刷新输出似乎可以正常工作(在Ubuntu 20.04上使用Python 3.8和PowerShell 7.0.1进行测试):

python3 -c "from time import *; print(time(), flush=True); sleep(3)" | python3 -c "from time import *; print(input()); print(time())"

在2ms之内给我时间戳记

在Windows上,flush=True选项似乎无法缓解问题,但是将第二个命令包装在ForEach-Object中确实可以解决问题:

python3 -c "from time import *; print(time(), flush=True); sleep(3)" |ForEach-Object { $_|python3 -c "from time import *; print(input()); print(time())" }

答案 1 :(得分:0)

在PowerShell中使用管道是关于将对象流从一个同步命令传递到另一个,而不是异步处理。

如果只需要并发处理,则可以使用作业。

您尚未指明要使用的PowerShell版本,所以我仅假设Windows PowerShell。

# Create your script block of code you want to execute in each thread/job
$ScriptBlock = {
    python -c "from time import *; print(time()); sleep(3)"
}

# A trivial example demonstrating that we can create 5 jobs to execute the same script block
$Jobs = 1..5 | ForEach-Object {
    Start-Job -ScriptBlock $ScriptBlock
}

# Wait for jobs to finish executing
Wait-Job $Jobs

# Receive the output data stream from all jobs
Get-Job $Jobs | Receive-Job

about_Jobs帮助主题中了解有关作业的更多信息:

Get-Help about_Jobs

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_jobs?view=powershell-5.1

答案 2 :(得分:0)

好吧,如果您想/需要使用管道,我建议您使用

ForEach-Object -Parallel

PowerShell ForEach-Object Parallel Feature

或者您也可以使用

workflow paralleltest {

 parallel {

  python -c "from time import *; print(time()); sleep(3)" | python -c "from time import *; print(input()); print(time())"

  }

PowerShell Workflows