在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

管道數據流"實時性" 和使用小提示

Linux愛好者 ? 來源:YXQ ? 2019-08-09 17:36 ? 次閱讀

相信很多在linux平臺工作的童鞋, 都很熟悉管道符 '|', 通過它, 我們能夠很靈活的將幾種不同的命令協同起來完成一件任務

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

其實我們在利用管道的時候, 可能會不經意的去想, 我前一個命令的輸出, 是全部處理完再通過管道傳給第二個命令, 還是一邊處理一邊輸出呢? 可能在大家是試驗中或者工作經驗中, 應該是左邊的命令全部處理完再一次性交給右邊的命令進行處理, 不光是大家, 我在最初接觸管道時, 也曾有這么一個誤會, 因為我們通過現象看到的就是這樣.

但其實只要有簡單了解過管道這工具, 應該都不難得出解釋:

管道是兩邊是同時進行, 也就是說, 左邊的命令輸出到管道, 管道的右邊將馬上進行處理.

管道的定義

管道是由內核管理的一個緩沖區,相當于我們放入內存中的一個紙條。管道的一端連接一個進程的輸出。這個進程會向管道中放入信息。管道的另一端連接一個進程的輸入,這個進程取出被放入管道的信息。一個緩沖區不需要很大,它被設計成為環形的數據結構,以便管道可以被循環利用。當管道中沒有信息的話,從管道中讀取的進程會等待,直到另一端的進程放入信息。當管道被放滿信息的時候,嘗試放入信息的進程會堵塞,直到另一端的進程取出信息。當兩個進程都終結的時候,管道也自動消失。

管道工作流程圖

通過上面的解釋可以看到, 假設 COMMAND1 | COMMAND2, 那么COMMAND1的標準輸出, 將會被綁定到管道的寫端, 而COMMAND2的標準輸入將會綁定到管道的讀端, 所以當COMMAND1一有輸出, 將會馬上通過管道傳給COMMAND2, 我們先來做個實驗驗證下:

#1.pyimporttimeimportsyswhile1:print'1111'time.sleep(3)print'2222'time.sleep(3)
[root@iZ23pynfq19Z~]#python1|cat

在上面的命令, 我們可以猜測下輸出結果: 究竟是 睡眠6秒之后, 輸出"1111222", 還是輸出 "1111" 睡眠3秒, 再輸出 "2222", 然后再睡眠3秒, 再輸出"1111" 呢? 答案就是: 都不是! what! 這不可能, 大家可以嘗試下, 我們會看到終端沒反應了, 為什么呢? 這就要涉及到文件IO的緩沖方式了,關于文件IO, 可以參考我的另一篇文章:淺談文件描述符1和2, 在最下面的地方提到文件IO的三種緩沖方式:

全緩沖:直到緩沖區被填滿,才調用系統I/O函數, (一般是針對文件)

行緩沖: 遇到換行符就輸出(標準輸出)

無緩沖:沒有緩沖區,數據會立即讀入或者輸出到外存文件和設備上(標準錯誤

因為python是默認采用帶緩沖的fputs(參考py27源碼: fileobject.c: PyFile_WriteString函數),又因為標準輸出被改寫到管道, 所以將會采取全緩沖的方式(shell 命令具體要看實現, 因為有些是用不帶緩沖write實現,如果不帶緩沖區,會直接寫入管道), 所以將會采取全緩沖的方式, 也就是說, 直到緩沖區被填滿, 或者手動顯示調用flush刷入,才能看到輸出.那我們可以將代碼改寫成下面兩種方式吧

#方式1:填滿緩沖區,我這邊大小是4096字節,你們也可以試下這個值,估計都一樣importtimeimportsyswhile1:print'1111'*4096time.sleep(3)print'2222'*4096time.sleep(3)#方式2:手動刷入寫隊列importtimeimportsyswhile1:print'1111'sys.stdout.flush()//因為是標準輸出,所以直接通過sys的接口去flushtime.sleep(3)print'2222'sys.stdout.flush()time.sleep(3)

輸出結果:


#第一種方式:[root@iZ23pynfq19Z~]#python1|cat1111.....(超多1,刷屏了..)睡眠3秒..2222.....(超多2,刷屏了..)#第二種方式:[root@iZ23pynfq19Z~]#python1|cat1111睡眠3秒..2222睡眠3秒..1111....

在這里我們已經能夠得出結果, 如果像我們以前所想的那樣, 要等到COMMAND1全部執行完才一次性輸出給COMMAND2, 那么結果應該是無限堵塞..因為我的程序一直沒有執行完..這樣應該是不符合老前輩們設計初衷的, 因為這樣可能會導致管道越來越大..然而管道也是有大小的~ 具體可以去看posix標準, 所以我們得出結論是: 只要COMMAND1的輸出寫入管道的寫端(不管是緩沖區滿還是手動flush), COMMAND2都將立刻得到數據并且馬上處理.

那么管道兩邊的數據流"實時性"討論到就先暫告一段落, 接下來將在這個基礎上繼續討論:管道使用的小提示.

在開始討論前, 我想先引入一個專業術語, 也是我們偶爾會遇到的, 那就是:SIGPIPE或者是一個更加具體的描述:broken pipe (管道破裂)

上面的專業術語都是跟管道讀寫規則息息相關的, 那咱們來看下 管道的讀寫規則吧:

當沒有數據可讀時

O_NONBLOCK (未設置):read調用阻塞,即進程暫停執行,一直等到有數據來到為止。

O_NONBLOCK ( 設置 ) :read調用返回-1,errno值為EAGAIN。

當管道滿的時候

O_NONBLOCK (未設置):write調用阻塞,直到有進程讀走數據

O_NONBLOCK ( 設置 ):調用返回-1,errno值為EAGAIN

如果所有管道寫端對應的文件描述符被關閉,則read返回0

如果所有管道讀端對應的文件描述符被關閉,則write操作會產生信號SIGPIPE

當要寫入的數據量不大于PIPE_BUF時,linux將保證寫入的原子性。

當要寫入的數據量大于PIPE_BUF時,linux將不再保證寫入的原子性。

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

咱們來重現下SIGPIPE

#!/usr/bin/pythonimporttimeimportsyswhile1:time.sleep(10)#手速不夠快的童鞋可以將睡眠時間設置長點print'1111'sys.stdout.flush()

這次執行命令需要考驗手速了, 因為我們要趕在py醒過來之前, 將讀端進程殺掉

python1|cat------------------------#另一個終端[root@iZ23pynfq19Z~]#ps-fe|grep-P'cat|python'root107754074000:05pts/200:00:00python1root107764074000:05pts/200:00:00cat#讀端進程root1083332581000:06pts/000:00:00grep-Pcat|python[root@iZ23pynfq19Z~]#kill10776

輸出結果

[root@iZ23pynfq19Z~]#python1|catTraceback(mostrecentcalllast):File"1",line6,insys.stdout.flush()IOError:[Errno32]BrokenpipeTerminated

從上圖我們可以驗證兩個點:

當我們殺掉讀端時, 寫端會收到SIGPIPE而默認退出, 管道結束

當我們殺掉讀端時, 寫端的程序并不會馬上收到SIGPIPE, 相反的, 只有真正寫入管道寫端時才會觸發這個錯誤

如果寫入一個 讀端已經關閉的管道, 將會收到一個SIGPIPE, 那讀一個寫端已經關閉的管道又會這樣呢?

importtimeimportsys#這次我們不需要死循環,因為我們想要寫端快點關閉退出time.sleep(5)print'1111'sys.stdout.flush()
#因為我們想要讀端等到足夠長的時間,讓寫端關閉,所以我們需要利用awk先睡眠10秒[root@iZ23pynfq19Z~]#python1.py|awk'{system("sleep10");print123}'------------------------[root@iZ23pynfq19Z~]#ps-fe|grep-P'awk|python'root117174074000:20pts/200:00:00python1.pyroot117184074000:20pts/200:00:00awk{system("sleep10");print123}root1172132581000:20pts/000:00:00grep-Pawk|python#5秒過后[root@iZ23pynfq19Z~]#ps-fe|grep-P'awk|python'root116854074000:20pts/200:00:00awk{system("sleep10");print123}root1169832581000:20pts/000:00:00grep-Pawk|python#10秒過后[root@iZ23pynfq19Z~]#python1|awk'{system("sleep10");print123}'123

在上面也已經證明了上文提到的讀寫規則: 如果所有管道寫端對應的文件描述符被關閉,將產生EOF結束標志,read返回0, 程序退出。

總結

通過上面的理論和實驗, 我們知道在使用管道時, 兩邊命令的數據傳輸過程, 以及對管道讀寫規則有了初步的認識, 希望我們以后在工作時, 再接觸管道時, 能夠更加有把握的去利用這一強大的工具。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11345

    瀏覽量

    210399
  • 管道
    +關注

    關注

    3

    文章

    145

    瀏覽量

    18023

原文標題:聊聊 Linux 的匿名管道

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    大眾數據流分析

    、3.0發動機數據流定義與解釋別克君威2.0發動機數據流定義與解釋凱越數據流列表凱越發動機數據流定義賽歐數據流列表賽歐
    發表于 06-15 12:28

    探測小提示

    選擇滿足示波器和應用需求的探頭,可以使您能夠進行必要的測量。實際上,進行測量和獲得有用的結果還取決于怎樣使用工具。下面的探測小提示將有助于您避免某些常見的測量問題。補償探頭大多數探頭是為與特定
    發表于 12-17 17:12

    部署實時數據流平臺面臨的挑戰有哪些?

    部署實時數據流平臺面臨的五大挑戰
    發表于 03-17 07:00

    LabVIEW數據流控制方法研究

    本文剖析了LabVIEW 數據流語言的特點,提供了其若干有效控制方法,指出LabVIEW 本身即可解決數據流控制上的變量沖突、響應時序控制、初始狀態自適應調整等問題并保證其通用
    發表于 07-30 11:39 ?13次下載

    基于數據流的Java字節碼分析

    本文基于數據流框架理論,提出了如何將數據流分析方法應用于JAVA 字節碼中,通過建立數據流與半格、數據流和函數調用圖的關系,從而對類型信息進行分析。實驗表明該
    發表于 12-25 13:22 ?9次下載

    網絡數據流存儲算法分析與實現

    針對網絡數據流存儲的瓶頸問題,提出了一種網絡數據流存儲算法分析與實現方法,仿真結果表明,模型能顯著提高網絡數據流實時存儲能力
    發表于 05-26 15:57 ?21次下載
    網絡<b class='flag-5'>數據流</b>存儲算法分析與實現

    基于FPGA芯片的數據流結構分析

    的兼容。 這里詳細介紹了Virtex 系列FPGA 芯片的數據流大小及結構。Virtex支持一些新的非常強大的配置模式,包括部分重新配置,這種配置機制被設計到高級應用中,以便通過芯片的配置接口能夠訪問及操作片內數據。但想要配置
    發表于 11-18 11:37 ?2413次閱讀

    數據流編程模型優化

    數據流編程模型將程序的計算與通信分離,暴露了應用程序潛在的并行并簡化了編程難度。分布式計算框架利用廉價PC構建多核集群解決了大規模并行計算問題,但多核集群層次存儲結構和處理單元對數據流
    發表于 11-23 15:48 ?3次下載
    <b class='flag-5'>數據流</b>編程模型優化

    數據環境下的分布式數據流處理關鍵技術探析

    數據環境下的數據流處理實時性要求高,數據計算要求持續和高可靠。分布式
    發表于 12-05 19:04 ?0次下載
    大<b class='flag-5'>數據</b>環境下的分布式<b class='flag-5'>數據流</b>處理關鍵技術探析

    數據流的網絡實時入侵檢測

    針對計算機網絡訪問請求具有實時到達以及動態變化的特點,為了實時檢測網絡入侵,并且適應網絡訪問數據的動態變化,提出一個基于數據流的網絡入侵實時
    發表于 01-17 10:09 ?0次下載
    <b class='flag-5'>數據流</b>的網絡<b class='flag-5'>實時</b>入侵檢測

    時間數據流的并行檢測算法

    針對現有長持續時間數據流檢測算法的實時差、檢測精度與估計精度低的問題,提出長持續時間數據流的并行檢測算法。基于共享數據結構的長持續時間
    發表于 03-06 15:54 ?0次下載
    時間<b class='flag-5'>數據流</b>的并行檢測算法

    數據流是什么

    數據流最初是通信領域使用的概念,代表傳輸中所使用的信息的數字編碼信號序列。然而,我們所提到的數據流概念與此不同。這個概念最初在1998年由Henzinger在文獻87中提出,他將數據流定義為“只能以事先規定好的順序被讀取一次的
    的頭像 發表于 02-27 15:25 ?7152次閱讀

    控制數據流的區別

    控制數據流的區別? 在計算機科學中,控制數據流是兩個非常重要的概念。雖然它們經常一起使用,但它們具有非常不同的含義。本文將討論控制
    的頭像 發表于 09-13 11:17 ?5855次閱讀

    示波器探頭的探測小提示

    選擇滿足示波器和應用需求的探頭,可以使您能夠進行必要的測量。實際上,進行測量和獲得有用的結果還取決于怎樣使用工具。下面的探測小提示將有助于您避免某些常見的測量問題: 補償探頭 大多數探頭是為與特定
    的頭像 發表于 07-23 10:53 ?274次閱讀
    示波器探頭的探測<b class='flag-5'>小提示</b>

    理解ECU數據流的分析方法

    隨著汽車電子化程度的提高,ECU在車輛中扮演的角色越來越重要。它們不僅控制著發動機管理、變速箱、制動系統等關鍵功能,還涉及到車輛的舒適和安全。 ECU數據流分析的重要 故障診斷
    的頭像 發表于 11-05 11:07 ?560次閱讀
    主站蜘蛛池模板: 久久不射影院 | 激情综合在线观看 | 好爽好深太大了再快一点 | 激情深爱| 国产精品大尺度尺度视频 | 嗯!啊!使劲用力在线观看 | 在线观看播放视频www | toyota东热综合网 | 亚洲伦理一区二区 | 黄蓉吕文德欲乱系列小说 | 拍拍拍无档又黄又爽视频 | 日本不卡一区 | 国产亚洲欧美视频 | 91啪在线视频 | 一区二区视屏 | 四虎www.| 国产网站在线 | 国精视频一区二区视频 | 手机在线观看毛片 | 亚洲国产影视 | 国产精品久久久久久久久免费hd | 国产欧美一区二区三区观看 | 成人99国产精品 | 四虎影院成人 | 国产精品黄网站免费进入 | 澳门久久精品 | 伊人久久大香线蕉综合电影 | 久久综合丁香 | 亚洲 欧洲 日韩 | 综合久久婷婷 | 亚洲免费小视频 | 午夜性视频| 日韩精品免费一区二区三区 | 日韩高清毛片 | 综合第一页 | 亚洲人成在线精品不卡网 | 黄色片网站大全 | 94久久国产乱子伦精品免费 | 在线精品国产第一页 | 欧美视频一区二区三区四区 | 天天伊人网 |