【问题标题】:Is pipe in linux asynchronous or not?linux中的管道是异步的吗?
【发布时间】:2021-08-26 15:03:02
【问题描述】:

我以为当我在命令下运行时

sleep 10 | sleep 2 | sleep 5   

Linux进程会

86014 ttys002    0:00.03 bash
86146 ttys002    0:00.00 sleep 10

sleep 10 结束时 -> sleep 2(睡眠 2 结束时)-> sleep 5
我是这么想的
但在 Linux bash 中,sleep 10, sleep 2, sleep 5ps 同时存在

sleep 10 进程的标准输出将被重定向到sleep 5 的进程
但是,在这种情况下,sleep 5 的进程将在sleep 10 之前完成

我很困惑,有没有关于这种现象的谷歌关键字或概念?

(我英文不好,可能这个文字看不懂????。谢谢)

【问题讨论】:

  • 我看不出你的困惑来源:sleep 不写入标准输出也不从标准输入读取,因此不使用管道。如果不需要同步,“命令管道”中的每个命令都将并行运行。您希望发生什么不同的事情?
  • @rodrigo 那么,当command 1 | command 2 没有情况下command2 在command 1 完成之前完成?我希望pipe connect -> fork -> run command1 -> command1 finished -> wait(command1's process) is end -> fork(for command2) -> run command2 -> finish 这个过程
  • 我正在重读您的问题并完全猜到了。我在下面的答案尝试...
  • 在通用的cmd1 | cmd2 中,第二个命令通常会阻塞从管道读取。在它读取它需要的所有数据之前,它不会完成。如果它不需要更多的数据,它还不如早点结束。

标签: linux redirect process pipe


【解决方案1】:

我认为您希望命令按顺序运行。但这不是管道的作用。

要按顺序运行两个命令,请使用;,我认为它被称为命令列表

$ time ( sleep 1 ; sleep 2 )
real    0m3.004s

您还可以使用&&(或||)创建命令列表,以便在一个命令返回失败(或成功)时中断序列。

但是,当您使用| 运行两个命令时,两者都是并行运行的,并且第一个的stdout 连接到第二个的stdin。这样,管道就充当了同步对象:

  • 如果第二个命令更快并清空管道,则在读取时它将等待更多数据
  • 如果第一个命令速度更快,并且向管道写入了太多数据,它的缓冲区将填满并阻塞,直到读取一些数据。
  • 此外,如果第二个命令死掉,一旦第一个命令写入stdout,它就会得到SIGPIPE,并且可能死掉。

(请注意,如果您的程序没有同时运行会发生什么情况:您的第一个程序可以将兆字节的文本写入stdout,并且没有人可以读取它,管道会溢出!)

但是由于sleep 不会读取或写入控制台,所以当您执行sleep 1 | sleep 2 时不会发生任何特殊情况,并且两者会同时运行。

管道中的 3 个或任何其他数量的命令也会发生同样的情况。

最终效果是完全睡眠时间最长:

$ time ( sleep 1 | sleep 2 | sleep 3 | sleep 4 )
real    0m4.004s

【讨论】:

  • “您的第一个程序可以将兆字节的文本写入控制台”。不,第一个程序可以将数据写入管道,但它没有向“控制台”写入任何内容。不要将标准输出与 tty 混为一谈。
  • 感谢您的 cmets 和回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 2016-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
相关资源
最近更新 更多