2017-02-14 64 views
0

我是Linux新手,我正在努力掌握管道和缓冲区的工作方式。 我看,如果我们在终端下输入:Unix - 如何改变一个伪终端的缓冲策略?

command1 | command2 

缓冲区将被刷新当它含有我们说4K的数据到标准输出。 从#1 How to make output of any shell command unbuffered?

另一个交我发现,一个可以“关闭”的缓冲器或改变缓冲策略使用伪终端到行缓冲。在这种情况下,实际上伪终端是如何工作的?为什么使用伪终端来改变缓冲策略?

谢谢!

+1

你在说什么“缓冲”?标准C'stdout'缓冲区由例如'printf'并且默认线路缓冲?管道本身使用的低级缓冲区?其他一些内核级缓冲区? –

回答

1

使用伪终端“工作”的原因是stdio库查看输出是否要去终端决定使用哪种缓冲策略。伪终端认为它正在与终端通话,所以它选择终端策略而不是“管道”策略。

+0

这是否意味着当我的输出进入终端时,它总是行缓冲? – newbie

+0

在这种情况下,行缓冲是默认值,但程序可以选择其他选项 - 在UNIXy系统上,请参阅“man setvbuf”以获取详细信息。 –

1

你的简单命令中涉及很多“缓冲区”。

  1. 在命令的代码里面可能会有一些缓冲。例如,如果使用C I/O,那么默认情况下在输出上有一个缓冲区。如果命令使用系统I/O,那么在输出上没有缓冲。
  2. Pipes提供了某种缓冲,它提供了生产者/消费者语义。字节存储在管道中,直到一次读取读取它们。
  3. 管道的第一个命令可以从tty中读取,最后一个可以写入到tty中,并且ttys有一个可能使用缓冲区的线路规则。

从您的角度来看,作为用户唯一可以玩的是终端的线路规范,以便提供的输入可以尽快提供或者通过某种烹饪或缓冲。可以使用命令stty来控制所有这些。

0

缓冲区将被刷新到标准输出,当它包含让我们说4K的数据。

您可能指的是臭名昭着的PIPE_BUF POSIX要求。这不是关于在一定大小后冲洗管道缓冲区。

PIPE_BUF要求是关于保证当多个进程每个写入小于PIPE_BUF到同一管道时,读取器将看不到来自不同进程的混合输入。

假设PIPE_BUF4(尽管它需要为至少512和是4096默认多数系统),和两个进程写入相同的管:

ProcessA: write(pipe, "abcd", 4) 
ProcessB: write(pipe, "EFG", 3) 
ProcessC: read(pipe, buf, 7) 

由于每个两个进程写小于或等于4字节,接收机将获得abcdEFGEFGabcd,但不是abEFGcdEFabcdG

这经常被错误地解释为“单个write()小于PIPE_BUF将通过另一侧上的单个read()检索”。