2017-02-14 65 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()檢索」。