13 進程間通訊: 管道

管道###

【11 章中筋量,我們看到一種在兩個進程間發(fā)送消息的非常簡單的方法: 使用信號岩灭;我們創(chuàng)建通知事件笆搓,通過它引起響應(yīng)膏蚓,但傳送的信息只限于一個信號值】
管道:通過它進程之間可以交換更有用的數(shù)據(jù)。
本章后:我們將學(xué)習(xí)到的知識將CD數(shù)據(jù)庫應(yīng)用程序重新實現(xiàn)為一個非常簡單的客戶/服務(wù)器應(yīng)用程序旷偿。

介紹大概:
(1)管道的定義
(2)進程管道
(3)管道調(diào)用
(4)父進程和子進程
(5)命名管道:FIFO
(6)客戶/服務(wù)器架構(gòu)

13.1 什么是管道烹俗?
當(dāng)從一個進程連接數(shù)據(jù)流到另一個進程時,我們使用術(shù)語:管道(pipe)萍程。
(我們通常是把一個進程的輸出通過管道連接到另一個進程的輸入)
大多數(shù)Linux的用于應(yīng)該早已對將shell命令連接在一起的概念很熟悉了幢妄,這實際上就是把一個進程的輸出直接傳遞給另外一個進程的輸入。(shell命令連接在一起茫负?蕉鸳??“|”)
eg: cmd1 | cmd2
對于shell命令倆說忍法,命令的連接是通過管道字符來完成的潮尝。【管道字符:“|”】
shell負責(zé)安排兩個命令的標(biāo)準輸入和標(biāo)準輸出
(1)cmd1 的標(biāo)準輸入來自終端的鍵盤
(2)cmd1 的標(biāo)準輸出傳遞給cmd2 饿序,作為它的標(biāo)準輸入勉失;
(3)cmd2的標(biāo)準輸出連接到終端屏幕。
. shell 所做的工作實際上就是對標(biāo)準輸入和標(biāo)準輸出流進行了重新連接原探,是數(shù)據(jù)連接從鍵盤輸入通過兩個命令最終輸出到屏幕上乱凿;

管道圖示

本章實現(xiàn)包含了 : 如何在程序中獲得這樣的效果,怎樣用管道將多個進程連接起來咽弦,從而實現(xiàn)一個簡單的客戶/服務(wù)器系統(tǒng)徒蟆。

13.2 進程管道###

兩個最簡單的在兩個程序之間傳遞數(shù)據(jù)的方法就是使用popen 和pclose 函數(shù)了。
頭文件: stdio.h
FILE *popen(const char *command, const cahr *open_mode);
int pclose(FILE *stream_to_close);
(1)popen 函數(shù)
popen 函數(shù)允許一個程序?qū)⒘硗庖粋€程序作為新進程啟動型型,并可以傳遞數(shù)據(jù)給它或者通過它接收數(shù)據(jù)段审。
command 字符串是要運行的程序名和相應(yīng)的參數(shù)。
open_mode 必須是“r”或“w”闹蒜;
如果open_mode 是“r”寺枉,被調(diào)用程序的輸出就可以被 調(diào)用程序使用抑淫,調(diào)用程序利用popen函數(shù)返回的FILE * 文件流指針,就可以通過常用的stdio庫函數(shù)(如:fread)來讀取被調(diào)用程序的輸出型凳;
如果open_mode 是“w”丈冬,調(diào)用程序就可以用fwrite 調(diào)用向被調(diào)用程序發(fā)送數(shù)據(jù),而被調(diào)通常用程序可以在自己的標(biāo)準輸入上讀取這些數(shù)據(jù)甘畅。被調(diào)用的程序通常不會意識到自己正在從另外一個進程讀取數(shù)據(jù),它只是在標(biāo)準輸入留上讀取數(shù)據(jù)往弓,然后做出相應(yīng)的操作疏唾。
每個popen調(diào)用都必須指定“r”或“w”,在popen函數(shù)的標(biāo)準實現(xiàn)中不支持任何其他選項函似。這意味著我們不能調(diào)用另外一個程序并同時對它進行讀寫操作(只可以選擇一個)槐脏。popen函數(shù)在失敗時返回一個空指針。如果想通過管道實現(xiàn)雙向通訊撇寞,最普通的解決方法是使用兩個管道顿天,每個管道負責(zé)一個方向的數(shù)據(jù)流。

(2)pclose函數(shù)####

用popen啟動的進程結(jié)束時蔑担,我們就可以用pclose函數(shù)關(guān)閉與之關(guān)聯(lián)的文件流牌废。##

pclose 調(diào)用值在popen啟動的進程結(jié)束后才返回。如果調(diào)用pclose時它仍然在云心啤握,pclose調(diào)用將等待該進程的結(jié)束鸟缕。
pclose 調(diào)用的返回值通常是它所關(guān)閉的文件流所在進程的退出碼。如果調(diào)用進程在調(diào)用pclose之前執(zhí)行了一個wait語句排抬,被調(diào)用進程的退出狀態(tài)就會丟失懂从,因為被調(diào)用進程已經(jīng)結(jié)束。此時蹲蒲,pclose將返回-1并設(shè)置errno為ECHILD番甩。

實驗:讀取外部程序的輸出###

打印系統(tǒng)信息命令

下面的示例是在程序中用popen訪問uname命令給出的信息。
大概過程 : 完成程序的初始化工作后届搁,打開一個連接到uname命令的管道缘薛,把管道設(shè)置為可讀方式并讓read_fp 指向命令的輸出。最后咖祭,關(guān)閉read_fp指向的管道掩宜。
代碼以及運行的結(jié)果

實驗解析: 這個程序用popen 調(diào)用啟動帶有-a選項的uname命令。然后用返回的文件流讀取最多BUFSIZge個字符(這個常量是stdio.h 中用#define 語句定義的)的數(shù)據(jù)么翰,并將它們打印出來顯示在屏幕上牺汤。因為我們是子啊程序內(nèi)部捕獲uname命令的輸出,所以可以處理它浩嫌。
實例代碼

13.3將輸出送往popen###

上面一個例子是捕獲外部程序輸出的例子檐迟;下面是將一個輸出發(fā)送到外部程序补胚。

示例代碼

這里是使用帶有參數(shù)“w”的popen 啟動od -c 命令,這樣就可以像該命令發(fā)送數(shù)據(jù)了追迟。然后它給od -c命令發(fā)送一個字符串溶其,該命令接受并且處理它,最后把處理結(jié)果打印到自己的標(biāo)準輸出上敦间。
相當(dāng)于:
等價命令

代碼

13.3.1 傳遞更多的數(shù)據(jù)####

目前所使員工的數(shù)據(jù)通過一個fread 或fwrite 調(diào)用來發(fā)送或接受瓶逃; 有時,我們可能希望以塊的方式發(fā)送數(shù)據(jù)廓块,或者我們根本不知道輸出數(shù)據(jù)的長度厢绝。為了避免頂一個分廠大的緩沖區(qū),我們可以用多個fread或fwrite調(diào)用數(shù)據(jù)分為幾部分處理带猴。


代碼需要調(diào)整昔汉,沒有獲取所說的結(jié)果

這個程序調(diào)用了popen函數(shù)使用“r”參數(shù),和popen1.c 程序的做法一樣拴清。這一次我們是連續(xù)從文件流中讀取數(shù)據(jù)靶病,知道沒有數(shù)據(jù)讀取為止】谟瑁【注意:雖然ps命令的執(zhí)行要花費一些時間娄周,單linux會安排好進程間的調(diào)度,讓兩個程序可以運行時繼續(xù)運行】如果進程popen3沒有數(shù)據(jù)可讀苹威,它將被掛起知道數(shù)據(jù)到達昆咽。如果寫進程ps產(chǎn)生的輸出超過了可用緩沖區(qū)的長度,它也會被掛起知道讀進程讀取一些數(shù)據(jù)牙甫。

13.3.2如何實現(xiàn)popen###

請求popen調(diào)用運行一個程序時掷酗,它首先啟動shell,即系統(tǒng)中的sh命令窟哺,然后將command字符串作為一個參數(shù)傳遞給它泻轰。這有兩個效果,一個好一個不太好且轨。
在Linux(Unix) 中浮声,所有參數(shù)擴展都是由于shell來完成的。所以旋奢,啟動程序之前先啟動shell來分析命令字符串泳挥,就可以使各種shell擴展(eg:c所指的是哪些文件)。在程序啟動之前就會全部完成至朗。這個功能是非常有用的屉符,它允許我們通過popen啟動非常復(fù)雜的shell命令。而其他一些創(chuàng)建進程的函數(shù)(eg:execl)調(diào)用起來就復(fù)雜很多,因為調(diào)用進程必須自己去完成shell擴展矗钟。
使用shell不太好的影響是:針對每個popen調(diào)用唆香,不僅要啟動一個唄請求的程序,還要啟動一個shell吨艇,即每個popen調(diào)用將多啟動兩個進程躬它。從節(jié)省系統(tǒng)資源的角度來看,popen函數(shù)的調(diào)用成本略搞东涡,而且對目標(biāo)命令的調(diào)用比正常方式要慢一些冯吓。
下面的命令: cat popen
.c | wc -l

代碼

shell在啟動后將popen*.c 擴展為一個文件列表,列表中的文件名都是以popen開頭软啼,以.c 結(jié)尾桑谍,shell還處理了管道符(|)并將cat命令的輸出傳遞給wc命令。我在一個popen調(diào)用中啟動了shell祸挪、cat 程序和wc程序,并進行了一次輸出重定向贞间。而調(diào)用這些命令的程序值看到最終的輸出結(jié)果贿条。

總結(jié)上面:
上面主要是關(guān)于什么是管道,就是進程之間的一種輸入和輸出的之間的信息交流增热。
進程管道的使用以及popen這個函數(shù)的使用整以。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市峻仇,隨后出現(xiàn)的幾起案子公黑,更是在濱河造成了極大的恐慌,老刑警劉巖摄咆,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凡蚜,死亡現(xiàn)場離奇詭異,居然都是意外死亡吭从,警方通過查閱死者的電腦和手機朝蜘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涩金,“玉大人谱醇,你說我怎么就攤上這事〔阶觯” “怎么了副渴?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長全度。 經(jīng)常有香客問我煮剧,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任轿秧,我火速辦了婚禮中跌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘菇篡。我一直安慰自己漩符,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布驱还。 她就那樣靜靜地躺著嗜暴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪议蟆。 梳的紋絲不亂的頭發(fā)上闷沥,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機與錄音咐容,去河邊找鬼舆逃。 笑死,一個胖子當(dāng)著我的面吹牛戳粒,可吹牛的內(nèi)容都是我干的路狮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼蔚约,長吁一口氣:“原來是場噩夢啊……” “哼奄妨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起苹祟,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤砸抛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后树枫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體直焙,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年团赏,在試婚紗的時候發(fā)現(xiàn)自己被綠了箕般。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡舔清,死狀恐怖丝里,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情体谒,我是刑警寧澤杯聚,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站抒痒,受9級特大地震影響幌绍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一傀广、第九天 我趴在偏房一處隱蔽的房頂上張望颁独。 院中可真熱鬧,春花似錦伪冰、人聲如沸誓酒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靠柑。三九已至,卻和暖如春吓懈,著一層夾襖步出監(jiān)牢的瞬間歼冰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工耻警, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留隔嫡,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓甘穿,卻偏偏與公主長得像畔勤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扒磁,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 進程間通信 進程間通信即IPC(InerProcess Communication)Unix ipc 已經(jīng)是而且繼...
    千里山南閱讀 457評論 0 2
  • 前言 管道是UNIX環(huán)境中歷史最悠久的進程間通信方式,也是最簡單的進程間通信方式式曲,一般用來作為IPC的入門妨托,最合適...
    GeekerLou閱讀 1,143評論 0 6
  • Variables A variable stores a piece of data, and gives it...
    燈盞細辛閱讀 241評論 0 0
  • 隨著六月的來臨兰伤,畢業(yè)開始籠上每個人的心頭,我不知道接下來的六月份會發(fā)生什么钧排,但我還是希望說一聲:畢業(yè)敦腔,請慢點。...
    張騫閱讀 230評論 0 0
  • "等待著你,等待你慢慢的靠近我糟袁,陪著我長長的夜到盡頭判族,別讓我獨自守候。等待著你项戴,等待你默默的凝望著我形帮,告訴我你的未...
    月夜松崗閱讀 336評論 0 4