|  | |||||||||
| 無名管道系統調用 | |||||||||
| 本文關鍵字: linux 管道通信,linux 進程通信方式 ,無名管道 1.管道創建(jian)與關閉說(shuo)明 管(guan)道(dao)(dao)是基于文(wen)件描述(shu)符的通信方式,當(dang)一個管(guan)道(dao)(dao)建立時,它會創建兩個文(wen)件描述(shu)符fd[0]和(he)fd[1],其中fd[0]固定用于讀管(guan)道(dao)(dao),而fd[1]固定用于寫(xie)管(guan)道(dao)(dao),如圖1所示,這樣就構成了一個半雙工的通道(dao)(dao)。 
 管道關閉(bi)時只需(xu)將(jiang)這兩個文件(jian)描述符關閉(bi)即可,可使用普通的(de)close()函數逐個關閉(bi)各(ge)個文件(jian)描述符。 2.管道(dao)創(chuang)建函數 創建管道(dao)可(ke)以通過(guo)調用pipe()來實現。表1列出了pipe()函(han)數的語法要點。 表1 pipe()函數語法要點 
 3.管道(dao)讀寫說明 用pipe()函數創建的管道兩端處于一個進程中,由于管道是主要用于在不同進程間通信的,因此在實際應用中沒有太大意義。實際上,通常先是創建一個管道,再調用fork()函數創建一個子進程(cheng),該子進程(cheng)會繼承父(fu)進程(cheng)所(suo)創建的管(guan)道,這時,父(fu)子進程(cheng)管(guan)道的文(wen)件描述符對應關系如圖2所(suo)示。 
 此(ci)時(shi)的(de)(de)(de)關系看似非常復雜,實際上卻已經給不同進(jin)(jin)程之間(jian)的(de)(de)(de)讀(du)寫創(chuang)造了(le)(le)很好的(de)(de)(de)條(tiao)件。父(fu)(fu)(fu)(fu)子進(jin)(jin)程分別擁(yong)有(you)自己的(de)(de)(de)讀(du)寫通(tong)道,為了(le)(le)實現父(fu)(fu)(fu)(fu)子進(jin)(jin)程之間(jian)的(de)(de)(de)讀(du)寫,只需把無關的(de)(de)(de)讀(du)端或(huo)寫端的(de)(de)(de)文件描述符(fu)關閉即可。例如,在圖3中(zhong)將(jiang)父(fu)(fu)(fu)(fu)進(jin)(jin)程的(de)(de)(de)寫端fd[1]和子進(jin)(jin)程的(de)(de)(de)讀(du)端fd[0]關閉。此(ci)時(shi),父(fu)(fu)(fu)(fu)子進(jin)(jin)程之間(jian)就建立(li)起了(le)(le)一條(tiao)“子進(jin)(jin)程寫入父(fu)(fu)(fu)(fu)進(jin)(jin)程讀(du)取”的(de)(de)(de)通(tong)道。 
 同樣,也(ye)可(ke)以關(guan)閉父進(jin)程(cheng)(cheng)(cheng)的(de)fd[0]和子進(jin)程(cheng)(cheng)(cheng)的(de)fd[1],這(zhe)樣就可(ke)以建(jian)立(li)一條“父進(jin)程(cheng)(cheng)(cheng)寫入子進(jin)程(cheng)(cheng)(cheng)讀(du)取(qu)”的(de)通道(dao)。另(ling)外(wai),父進(jin)程(cheng)(cheng)(cheng)還(huan)可(ke)以創建(jian)多個(ge)子進(jin)程(cheng)(cheng)(cheng),各個(ge)子進(jin)程(cheng)(cheng)(cheng)都繼(ji)承了(le)相(xiang)應的(de)fd[0]和fd[1]。這(zhe)時,只需關(guan)閉相(xiang)應端(duan)口就可(ke)以建(jian)立(li)其(qi)各子進(jin)程(cheng)(cheng)(cheng)間的(de)通道(dao)。   4.管道(dao)讀寫(xie)注意(yi)點(dian) 管(guan)道讀(du)寫需注意以下幾點: ● 只有在管(guan)道(dao)的讀端存在時,向管(guan)道(dao)寫(xie)入數據才有意義(yi)。否則,向管(guan)道(dao)寫(xie)入數據的進(jin)程將收到內核傳來的SIGPIPE信號(通常為(wei)Broken pipe錯誤)。 ● 向管道寫入數(shu)據(ju)(ju)(ju)時(shi),Linux將不保證寫入的原子性,管道緩沖區一有空閑區域,寫進程就(jiu)會試圖向管道寫入數(shu)據(ju)(ju)(ju)。如果讀進程不讀取管道緩沖區中的數(shu)據(ju)(ju)(ju),那么(me)寫操作將會一直阻塞。 ● 父子(zi)進(jin)程在(zai)運行時(shi),它們的(de)(de)先后(hou)次序(xu)并(bing)不能(neng)保證(zheng)。因此,為了保證(zheng)父子(zi)進(jin)程已經關閉(bi)了相應的(de)(de)文件描述符,可在(zai)兩(liang)個進(jin)程中調(diao)(diao)用sleep()函數(shu)。當(dang)然這種調(diao)(diao)用不是(shi)很好的(de)(de)解(jie)決方法,在(zai)后(hou)面(mian)學(xue)到進(jin)程之間的(de)(de)同步(bu)機制(zhi)與互斥機制(zhi)后(hou),請讀者自行修改本(ben)小節(jie)的(de)(de)實例程序(xu)。 5.使用實(shi)例 在本(ben)例中,首(shou)先創建管(guan)道,之(zhi)后父進(jin)程(cheng)(cheng)使用fork()函數創建子進(jin)程(cheng)(cheng),后通過關閉父進(jin)程(cheng)(cheng)的讀描述符和子進(jin)程(cheng)(cheng)的寫描述符,建立起它們之(zhi)間的管(guan)道通信。     /* pipe.c */   將該程序交叉編譯,下載到開發板上的(de)運行結果如下:     $ ./pipe 本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發》 熱點(dian)鏈接:  
         1、Linux下進程間通信方式-管道 |