管道作为并行命令

管道作为并行命令

通常,Unix 中的管道用于连接两个命令,并将第一个命令的输出作为第二个命令的输入。然而,我最近提出了使用管道并行运行多个命令的想法(这可能并不新鲜,但我没有找到太多谷歌搜索),如下所示:

command1 | command2

这将并行调用command1command2ifcommand2不从标准输入读取也不command1写入标准输出t. 一个最小的例子来说明这一点(请在交互式 shell 中运行它)

ls . -R 1>&2|ls . -R

我的问题是,使用管道以这种方式并行执行两个命令有什么缺点吗?这个想法有什么我错过的吗?

预先非常感谢您。

答案1

命令管道已经并行运行。使用命令:

command1 | command2

command1和都已command2启动。如果command2已调度且管道为空,则它会阻塞等待读取。如果command1尝试写入管道且管道已满,command1则会阻塞,直到有空间可写入。否则,command1command2都会并行执行,写入管道和从管道读取。

答案2

有缺点...

  1. 你看不到的输出command1
  2. 如果command2不读取 的输出command1,后者将在写入一定量的输出后挂起(我见过 4K,但根据实验,至少对于 python 进程来说,限制在 58K 左右,见下文)。这可能取决于 所使用的运行时command1
  3. 如果command2之前停止command1command1写入其标准输出,它将得到[Errno 32] Broken pipe

实验:

指令1
#! /usr/bin/python3

import sys,time
for i in range(64):
    print ("*"*1023,file=sys.stdout)
    print ("cmd1 here (%d)" % i,file=sys.stderr)
    time.sleep(.1)
print ("cmd1 exiting",file=sys.stderr)
指令2
#! /usr/bin/python3

import sys,time
for i in range(16):
    print ("cmd2 here (%d)" % i,file=sys.stderr)
    time.sleep(1)
print ("cmd2 exiting",file=sys.stderr)

跑步:

./cmd1 | ./cmd2

你会看见:

  • cmd1在迭代 58 处停止(因为 cmd2 从未从其输出中读取任何内容)
  • cmd1cmd2 退出时崩溃(管道损坏)

所以是的,也许它可以起作用。也许不是。

相关内容