![]() |
|||||||||
無名管道系統(tǒng)調(diào)用 |
|||||||||
本文關鍵字: linux 管道通信,linux 進程通信方式 ,無名管道 1.管道創(chuàng)建與關閉說明 管道是基于文件描述符的通信方式,當一個管道建立時,它會創(chuàng)建兩個文件描述符fd[0]和fd[1],其中fd[0]固定用于讀管道,而fd[1]固定用于寫管道,如圖1所示,這樣就構成了一個半雙工的通道。
管道關閉時只需將這兩個文件描述符關閉即可,可使用普通的close()函數(shù)逐個關閉各個文件描述符。 2.管道創(chuàng)建函數(shù) 創(chuàng)建管道可以通過調(diào)用pipe()來實現(xiàn)。表1列出了pipe()函數(shù)的語法要點。 表1 pipe()函數(shù)語法要點
3.管道讀寫說明 用pipe()函數(shù)創(chuàng)建的管道兩端處于一個進程中,由于管道是主要用于在不同進程間通信的,因此在實際應用中沒有太大意義。實際上,通常先是創(chuàng)建一個管道,再調(diào)用fork()函數(shù)創(chuàng)建一個子進程,該子進程會繼承父進程所創(chuàng)建的管道,這時,父子進程管道的文件描述符對應關系如圖2所示。
此時的關系看似非常復雜,實際上卻已經(jīng)給不同進程之間的讀寫創(chuàng)造了很好的條件。父子進程分別擁有自己的讀寫通道,為了實現(xiàn)父子進程之間的讀寫,只需把無關的讀端或?qū)懚说奈募枋龇P閉即可。例如,在圖3中將父進程的寫端fd[1]和子進程的讀端fd[0]關閉。此時,父子進程之間就建立起了一條“子進程寫入父進程讀取”的通道。
同樣,也可以關閉父進程的fd[0]和子進程的fd[1],這樣就可以建立一條“父進程寫入子進程讀取”的通道。另外,父進程還可以創(chuàng)建多個子進程,各個子進程都繼承了相應的fd[0]和fd[1]。這時,只需關閉相應端口就可以建立其各子進程間的通道。 4.管道讀寫注意點 管道讀寫需注意以下幾點: ● 只有在管道的讀端存在時,向管道寫入數(shù)據(jù)才有意義。否則,向管道寫入數(shù)據(jù)的進程將收到內(nèi)核傳來的SIGPIPE信號(通常為Broken pipe錯誤)。 ● 向管道寫入數(shù)據(jù)時,Linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進程就會試圖向管道寫入數(shù)據(jù)。如果讀進程不讀取管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將會一直阻塞。 ● 父子進程在運行時,它們的先后次序并不能保證。因此,為了保證父子進程已經(jīng)關閉了相應的文件描述符,可在兩個進程中調(diào)用sleep()函數(shù)。當然這種調(diào)用不是很好的解決方法,在后面學到進程之間的同步機制與互斥機制后,請讀者自行修改本小節(jié)的實例程序。 5.使用實例 在本例中,首先創(chuàng)建管道,之后父進程使用fork()函數(shù)創(chuàng)建子進程,后通過關閉父進程的讀描述符和子進程的寫描述符,建立起它們之間的管道通信。 /* pipe.c */ 將該程序交叉編譯,下載到開發(fā)板上的運行結果如下: $ ./pipe 本文選自華清遠見嵌入式培訓教材《從實踐中學嵌入式Linux應用程序開發(fā)》 熱點鏈接:
1、Linux下進程間通信方式-管道 |