【问题标题】:Are Unix/Linux pipes producer or consumer driven?Unix/Linux 管道是生产者驱动还是消费者驱动?
【发布时间】:2014-01-20 04:34:33
【问题描述】:

假设我有这个:

A | B | C

管道是如何工作的? A 是否仅在 B 请求时才生成数据?如果 B 目前不能接受,A 是否会不断产生数据然后阻塞? C的作用是什么?我意识到我正在设计的系统在概念上与这些管道非常相似——我想利用现有的范式,而不是发明一些只能起到一半效果的新奇事物。

【问题讨论】:

  • 您能详细介绍一下您的流程吗?如果 B 不读取 STDIN ,那么 A 所做的和 C 一样的都无关紧要
  • 是的,B 将从 A 中读取(而 C 从 B 中读取)。 A 和 B 也会写信给stdout.
  • A 、 B 或 C 可以根据需要终止管道,例如: cat largefile |头-n1 | grep 'test' : 只读取一条记录,全部结束
  • en.wikipedia.org/wiki/Pipeline_(Unix)有一些关于实现的简要说明

标签: linux bash shell unix pipe


【解决方案1】:

Unix 中的管道有一个缓冲区,因此即使右侧进程 (RSP) 不消耗任何数据,左侧进程 (LSP) 也能够在阻塞之前产生几千字节。

然后,如果缓冲区满了,LSP 最终会被阻塞。当 RSP 读取数据时,它会释放部分或全部缓冲区空间,然后 LSP 恢复操作。

如果你有 3 个进程而不是 2 个进程,情况大致相同:更快的生产者被更慢的消费者阻塞。显然,如果管道变空,速度较快的消费者会被较慢的生产者阻塞:想想一个交互式外壳,等待所有最慢的生产者:用户。

例如以下命令:

$ yes | cat | more

由于more 在屏幕满屏时阻塞,直到用户按下一个键,cat 进程将填充其输出缓冲区并停止,然后yes 进程将填充其缓冲区并停止。一切都在等待用户继续,应该是这样。

PS:一个有趣的事实是:当more 进程结束时会发生什么?好吧,该管道的右侧已关闭,因此cat 进程将获得SIGPIPE 信号(如果它再次在管道中写入,它会)并且将死亡。 yes 进程也会发生同样的情况。所有进程都死掉了,这是应该的。

【讨论】:

  • 优秀的描述。使用行号 $ yes | 可视化 yes 输出对更多人很有帮助。猫-n |更多
【解决方案2】:

A 有一个到 B 的管道,B 有一个到 C 的管道。每个管道都有一个缓冲区;如果 B 和 C 尝试读取,并且没有任何可用输入(流结束计为输入),则它们会阻塞。如果 A 和 B 有输出要写入,则阻塞,但管道的缓冲区已满。

所有三个进程同时运行,尽可能多地使用 CPU。如果管道缓冲区已耗尽/已满,操作系统会根据需要在读/写系统调用中阻止它们。

所以,它们是由消费者和生产者共同驱动的,也就是说,速率是消耗速率和生产速率的最小值。如果消费者更快,则性能由生产者驱动,而vv。

【讨论】:

    猜你喜欢
    • 2019-12-10
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多