亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

你所不知道的linux匿名管道知識(shí)

相信很多在Linux平臺(tái)工作的童鞋, 都很熟悉管道符 '|', 通過它, 我們能夠很靈活的將幾種不同的命令協(xié)同起來完成一件任務(wù)。就好像下面的命令:

你所不知道的linux匿名管道知識(shí)

不過這次咱們不來說這些用法, 而是來探討一些更加有意思的, 那就是?管道兩邊的數(shù)據(jù)流"實(shí)時(shí)性"?和?管道使用的小提示。

其實(shí)我們?cè)诶霉艿赖臅r(shí)候, 可能會(huì)不經(jīng)意的去想, 我前一個(gè)命令的輸出, 是全部處理完再通過管道傳給第二個(gè)命令, 還是一邊處理一邊輸出呢? 可能在大家是試驗(yàn)中或者工作經(jīng)驗(yàn)中, 應(yīng)該是左邊的命令全部處理完再一次性交給右邊的命令進(jìn)行處理, 不光是大家, 我在最初接觸管道時(shí), 也曾有這么一個(gè)誤會(huì), 因?yàn)槲覀兺ㄟ^現(xiàn)象看到的就是這樣。

但其實(shí)只要有簡(jiǎn)單了解過管道這工具, 應(yīng)該都不難得出解釋:

管道是兩邊是同時(shí)進(jìn)行, 也就是說, 左邊的命令輸出到管道, 管道的右邊將馬上進(jìn)行處理。

管道的定義

管道是由內(nèi)核管理的一個(gè)緩沖區(qū),相當(dāng)于我們放入內(nèi)存中的一個(gè)紙條。管道的一端連接一個(gè)進(jìn)程的輸出。這個(gè)進(jìn)程會(huì)向管道中放入信息。管道的另一端連接一個(gè)進(jìn)程的輸入,這個(gè)進(jìn)程取出被放入管道的信息。一個(gè)緩沖區(qū)不需要很大,它被設(shè)計(jì)成為環(huán)形的數(shù)據(jù)結(jié)構(gòu),以便管道可以被循環(huán)利用。當(dāng)管道中沒有信息的話,從管道中讀取的進(jìn)程會(huì)等待,直到另一端的進(jìn)程放入信息。當(dāng)管道被放滿信息的時(shí)候,嘗試放入信息的進(jìn)程會(huì)堵塞,直到另一端的進(jìn)程取出信息。當(dāng)兩個(gè)進(jìn)程都終結(jié)的時(shí)候,管道也自動(dòng)消失。

你所不知道的linux匿名管道知識(shí)

管道工作流程圖

通過上面的解釋可以看到, 假設(shè) COMMAND1 | COMMAND2, 那么COMMAND1的標(biāo)準(zhǔn)輸出, 將會(huì)被綁定到管道的寫端, 而COMMAND2的標(biāo)準(zhǔn)輸入將會(huì)綁定到管道的讀端, ?所以當(dāng)COMMAND1一有輸出, 將會(huì)馬上通過管道傳給COMMAND2, 我們先來做個(gè)實(shí)驗(yàn)驗(yàn)證下:

你所不知道的linux匿名管道知識(shí)

你所不知道的linux匿名管道知識(shí)

在上面的命令, 我們可以猜測(cè)下輸出結(jié)果: 究竟是 睡眠6秒之后, 輸出"1111222", 還是輸出 "1111" 睡眠3秒, 再輸出 "2222", 然后再睡眠3秒, 再輸出"1111" 呢? 答案就是: 都不是! what! 這不可能, 大家可以嘗試下, 我們會(huì)看到終端沒反應(yīng)了, ?為什么呢? 這就要涉及到文件IO的緩沖方式了,這里不多說, 簡(jiǎn)單提一下文件IO的三種緩沖方式:

  • 全緩沖:?直到緩沖區(qū)被填滿,才調(diào)用系統(tǒng)I/O函數(shù), (一般是針對(duì)文件)
  • 行緩沖: 遇到換行符就輸出(標(biāo)準(zhǔn)輸出)
  • 無緩沖:?沒有緩沖區(qū),數(shù)據(jù)會(huì)立即讀入或者輸出到外存文件和設(shè)備上(標(biāo)準(zhǔn)錯(cuò)誤

因?yàn)镻ython是默認(rèn)采用帶緩沖的fputs,?又因?yàn)闃?biāo)準(zhǔn)輸出被改寫到管道, 所以將會(huì)采取全緩沖的方式(shell 命令具體要看實(shí)現(xiàn), 因?yàn)橛行┦怯貌粠Ь彌_write實(shí)現(xiàn),如果不帶緩沖區(qū),會(huì)直接寫入管道), 所以將會(huì)采取全緩沖的方式, 也就是說, 直到緩沖區(qū)被填滿, 或者手動(dòng)顯示調(diào)用flush刷入,才能看到輸出。那我們可以將代碼改寫成下面兩種方式吧

你所不知道的linux匿名管道知識(shí)

輸出結(jié)果:

你所不知道的linux匿名管道知識(shí)

在這里我們已經(jīng)能夠得出結(jié)果, 如果像我們以前所想的那樣, 要等到COMMAND1全部執(zhí)行完才一次性輸出給COMMAND2, 那么結(jié)果應(yīng)該是無限堵塞。因?yàn)槲业某绦蛞恢睕]有執(zhí)行完。這樣應(yīng)該是不符合老前輩們?cè)O(shè)計(jì)初衷的, 因?yàn)檫@樣可能會(huì)導(dǎo)致管道越來越大。然而管道也是有大小的~ 具體可以去看posix標(biāo)準(zhǔn), 所以我們得出結(jié)論是: 只要COMMAND1的輸出寫入管道的寫端(不管是緩沖區(qū)滿還是手動(dòng)flush), COMMAND2都將立刻得到數(shù)據(jù)并且馬上處理。

那么?管道兩邊的數(shù)據(jù)流"實(shí)時(shí)性"?討論到就先暫告一段落, 接下來將在這個(gè)基礎(chǔ)上繼續(xù)討論:?管道使用的小提示。

在開始討論前, 我想先引入一個(gè)專業(yè)術(shù)語, 也是我們偶爾會(huì)遇到的, 那就是:?SIGPIPE。

或者是一個(gè)更加具體的描述:?broken pipe(管道破裂)

上面的專業(yè)術(shù)語都是跟管道讀寫規(guī)則息息相關(guān)的, 那咱們來看下 管道的讀寫規(guī)則吧:

1.當(dāng)沒有數(shù)據(jù)可讀時(shí)

  • O_NONBLOCK (未設(shè)置):read調(diào)用阻塞,即進(jìn)程暫停執(zhí)行,一直等到有數(shù)據(jù)來到為止。
  • O_NONBLOCK ?( 設(shè)置 ) :read調(diào)用返回-1,errno值為EAGAIN。

2.當(dāng)管道滿的時(shí)候

  • O_NONBLOCK (未設(shè)置): write調(diào)用阻塞,直到有進(jìn)程讀走數(shù)據(jù)
  • O_NONBLOCK ( 設(shè)置 ):調(diào)用返回-1,errno值為EAGAIN

3.如果所有管道寫端對(duì)應(yīng)的文件描述符被關(guān)閉,則read返回0

4.如果所有管道讀端對(duì)應(yīng)的文件描述符被關(guān)閉,則write操作會(huì)產(chǎn)生信號(hào)SIGPIPE

5.當(dāng)要寫入的數(shù)據(jù)量不大于PIPE_BUF時(shí),Linux將保證寫入的原子性。

6.當(dāng)要寫入的數(shù)據(jù)量大于PIPE_BUF時(shí),Linux將不再保證寫入的原子性。

在上面我們可以看到, 如果我們收到SIGPIPE信號(hào), 那么一般情況就是讀端被關(guān)閉, 但是寫端卻依舊嘗試寫入

咱們來重現(xiàn)下?SIGPIPE

你所不知道的linux匿名管道知識(shí)

這次執(zhí)行命令需要考驗(yàn)手速了, 因?yàn)槲覀円s在py醒過來之前, 將讀端進(jìn)程殺掉

你所不知道的linux匿名管道知識(shí)

輸出結(jié)果

你所不知道的linux匿名管道知識(shí)

從上圖我們可以驗(yàn)證兩個(gè)點(diǎn):

  1. 當(dāng)我們殺掉讀端時(shí), 寫端會(huì)收到SIGPIPE而默認(rèn)退出, 管道結(jié)束
  2. 當(dāng)我們殺掉讀端時(shí), 寫端的程序并不會(huì)馬上收到SIGPIPE, 相反的, 只有真正寫入管道寫端時(shí)才會(huì)觸發(fā)這個(gè)錯(cuò)誤

如果寫入一個(gè) 讀端已經(jīng)關(guān)閉的管道, 將會(huì)收到一個(gè)?SIGPIPE, 那讀一個(gè)寫端已經(jīng)關(guān)閉的管道又會(huì)這樣呢?

你所不知道的linux匿名管道知識(shí)

你所不知道的linux匿名管道知識(shí)

在上面也已經(jīng)證明了上文提到的讀寫規(guī)則:?如果所有管道寫端對(duì)應(yīng)的文件描述符被關(guān)閉,將產(chǎn)生EOF結(jié)束標(biāo)志,read返回0, 程序退出

總結(jié)

通過上面的理論和實(shí)驗(yàn), 我們知道在使用管道時(shí), 兩邊命令的數(shù)據(jù)傳輸過程, 以及對(duì)管道讀寫規(guī)則有了初步的認(rèn)識(shí), 希望我們以后在工作時(shí), 再接觸管道時(shí), 能夠更加有把握的去利用這一強(qiáng)大的工具。

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國(guó)內(nèi)好評(píng)如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!