在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,而不处理普通的可执行文件。
答案 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
答案 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())"
}