Unix / Linux管道是生产者还是消费者驱动?

时间:2014-01-02 17:04:21

标签: linux bash shell unix pipe

假设我有这个:

A | B | C

管道如何运作? A只在B请求时产生数据吗?如果B目前无法接受,A是否会持续生成数据然后阻止?什么是C的角色?我意识到我正在设计的系统在概念上与这些管道非常相似 - 我想借鉴现有的范例,而不是发明一些只能工作一半的小说。

2 个答案:

答案 0 :(得分:13)

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

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

如果您有3个进程而不是2个进程,则情况大致相同:更快的生产者被更慢的消费者阻止。显然,如果管道变空,更快的消费者会被生产者放慢阻塞:只需要想一个交互式shell,等待所有人中最慢的生产者:用户。

例如以下命令:

$ yes | cat | more

由于more在屏幕已满时阻塞,直到用户按下某个键,cat进程将填充其输出缓冲区并停止,然后yes进程将填充其缓冲区并且还失速。等待用户继续的一切,应该如此。

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

答案 1 :(得分:2)

A有一个到B的管道,B有一个到C的管道。每个管道有一个缓冲区; B和C阻塞,如果他们尝试读取,并且没有任何可用输入(流末端计数作为输入)。 A和B阻塞,如果他们有输出写,但管道的缓冲区已满。

所有三个进程同时运行,使用尽可能多的CPU。如果管道缓冲区分别耗尽/满,OS会在读/写系统调用中阻塞它们。

因此,他们受到消费者和生产者的驱动,也就是说,费率是消费率和生产率的最小值。如果消费者更快,则性能由生产者和vv。

驱动