考虑以下简单命令:
cmd1 | cmd2
cmd2
开始执行
cmd1
一经输出cmd1
完全完成并退出后?在情况1中,cmd1
的输出速度比cmd2
消耗的速度快,或者简单地在情况2中,中间输出必须有一个缓冲区。
答案 0 :(得分:2)
library(tidyverse)
df %>%
group_by(id) %>%
nest()
## A tibble: 4 x 2
# id data
# <int> <list>
#1 1 <tibble [3 × 6]>
#2 2 <tibble [1 × 6]>
#3 3 <tibble [1 × 6]>
#4 4 <tibble [2 × 6]>
和df <- read.table(text =
" id date x1 x2 x3 x4 x5
1 2009-01-01 5 4 2 5.5 7
1 2009-01-02 5.4 4.1 2.2 5.3 7.1
1 2009-01-03 4.4 2.1 4.2 6.3 10.1
2 2009-01-01 12.4 2.7 4.9 3.3 2.1
3 2010-01-01 3.4 1.7 4.6 4.3 6.1
4 2009-01-01 2.4 3.7 5.6 2.3 9.1
4 2009-01-02 3.4 5.7 7.6 3.3 5.1", header = T)
并行运行,都立即启动cmd1
更快,它将在写入管道时阻塞。它不会继续写入,也不需要额外的缓冲区空间。cmd2
更快,则会在读取管道时阻塞cmd1
首先退出,则管道关闭,cmd2
将其解释为文件结束并停止cmd1
首先退出,则管道将关闭,并且cmd2
将在下次写入时收到SIGPIPE,通常会杀死它。答案 1 :(得分:2)
cmd2
程序立即开始运行,但是只要尝试读取输入,它将在必要时“阻塞”(停止并等待),直到有可用的为止。这是由内核自动完成的。除此之外,这两个程序可以同时运行(包括在不同的CPU内核上同时运行)。
两个进程之间的缓冲区由内核保存,并在内存中(尽管可能可以将其分页出来-我不确定)。缓冲区的 default 大小似乎不是可配置的,但是程序可以为特定管道请求更大的大小,并且 的限制可通过写以下命令来配置/proc/sys/fs/pipe-max-size
文件(位于/proc
中,实际上不是磁盘上的文件;它是访问内核中设置的虚拟文件。)有关更多信息,请参见this question。
如果cmd1
试图写入但缓冲区已满,它将阻塞直到缓冲区中的某些空间可用为止(cmd2
读取某些缓冲数据时会发生这种情况)。因此,如果cmd1
产生的输出太快,则必须等待cmd2
消耗输出,从而自动降低输出速度。
如果缓冲区很小,则程序在等待时可能会更频繁地阻塞,这可能会使它们花费更长的时间才能完成,因为它们将花费更多的时间等待。
通常,大多数管道可能分为两类:
cmd1
产生的输出要比cmd2
消耗的输出快:缓冲区通常已满(或接近缓冲区),并且cmd1
在尝试写入时经常阻塞,这会减慢其匹配速度cmd2
的速度。 cmd2
之所以能够全速运行,是因为缓冲区中始终有可用的输入,因此几乎不需要阻塞读取。cmd2
消耗的输入速度比cmd1
产生输入的速度快:缓冲区通常为空(或接近缓冲区),并且cmd2
在尝试读取时经常阻塞,这将其减慢到匹配cmd1
的速度。 cmd1
之所以能够全速运行,是因为始终有足够的空间可写入缓冲区,因此它几乎不必阻塞写入。