Linux程序間的通訊 管道

2021-07-05 03:20:16 字數 2869 閱讀 2204

linux程序間的通訊——管道

訊號可以看作一種粗糙的程序間通訊(ipc, interprocess communication)的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種:

乙個原始的ipc方式是所有的程序通過乙個檔案交流。比如我在紙(檔案)上寫下我的名字和年紀。另乙個人讀這張紙,會知道我的名字和年紀。他也可以在同一張紙上寫下他的資訊,而當我讀這張紙的話,同樣也可以知道別人的資訊。但是,由於硬碟讀寫比較慢,所以這個方式效率很低。那麼,我們是否可以將這張紙放入記憶體中以提高讀寫速度呢?

在linux文字流中,我們已經講解了如何在shell中使用管道連線多個程序。同樣,許多程式語言中,也有一些命令用以實現類似的機制,比如在python子程序中使用popen和pipe,在c語言中也有popen庫函式來實現管道 (shell中的管道就是根據此編寫的)。管道是由核心管理的乙個緩衝區(buffer),相當於我們放入記憶體中的乙個紙條。管道的一端連線乙個程序的輸出。這個程序會向管道中放入資訊。管道的另一端連線乙個程序的輸入,這個程序取出被放入管道的資訊。乙個緩衝區不需要很大,它被設計成為環形的資料結構,以便管道可以被迴圈利用。當管道中沒有資訊的話,從管道中讀取的程序會等待,直到另一端的程序放入資訊。當管道被放滿資訊的時候,嘗試放入資訊的程序會等待,直到另一端的程序取出資訊。當兩個程序都終結的時候,管道也自動消失。

從原理上,管道利用fork機制建立,從而讓兩個程序可以連線到同乙個pipe上。最開始的時候,上面的兩個箭頭都連線在同乙個程序process 1上(連線在process 1上的兩個箭頭)。當fork複製程序的時候,會將這兩個連線也複製到新的程序(process 2)。隨後,每個程序關閉自己不需要的乙個連線 (兩個黑色的箭頭被關閉; process 1關閉從pipe來的輸入連線,process 2關閉輸出到pipe的連線),這樣,剩下的紅色連線就構成了如上圖的pipe。

由於基於fork機制,所以管道只能用於父程序和子程序之間,或者擁有相同祖先的兩個子程序之間 (有親緣關係的程序之間)。為了解決這一問題,linux提供了fifo方式連線程序。fifo又叫做命名管道(named pipe)。

fifo (first in, first out)為一種特殊的檔案型別,它在檔案系統中有對應的路徑。當乙個程序以讀(r)的方式開啟該檔案,而另乙個程序以寫(w)的方式開啟該檔案,那麼核心就會在這兩個程序之間建立管道,所以fifo實際上也由核心管理,不與硬碟打交道。之所以叫fifo,是因為管道本質上是乙個先進先出的佇列資料結構,最早放入的資料被最先讀出來(好像是傳送帶,一頭放貨,一頭取貨),從而保證資訊交流的順序。fifo只是借用了檔案系統(file system)來為管道命名。寫模式的程序向fifo檔案中寫入,而讀模式的程序從fifo檔案中讀出。當刪除fifo檔案時,管道連線也隨之消失。fifo的好處在於我們可以通過檔案的路徑來識別管道,從而讓沒有親緣關係的程序之間建立連線。

無名管道,在父子程序中實現管道

pipo_rw

#include

#include

#include

#include

#include

#include

int main()

/*建立子程序*/

if((pid=fork())==0)  //子程序執行序列

close(pipe_fd[0]);

exit(0);

}else if(pid>0) //父程序執行序列

return 0;

}有名管道,需要建立兩個程序

fifo_write

#include

#include

#include

#include

#include

#include

#include

#define fifo_server "/tmp/myfifo"

int main(int argc,char** argv)

/*入參檢測*/

if(argc==1)

strcpy(w_buf,argv[1]);

/* 向管道寫入資料 */

if((nwrite=write(fd,w_buf,100))==-1)

else

printf("write %s to the fifo\n",w_buf);

close(fd); //關閉管道

return 0;

}fifo_read

#include

#include

#include

#include

#include

#include

#include

#define fifo "/tmp/myfifo"

int main(int argc,char** argv)

while(1)

printf("read %s from fifo\n",buf_r);

sleep(1);

}//後面三句話是不會被執行到的,但不會影響程式執行的效果當程式在上面的死迴圈中執行時收到訊號後會馬上結束執行而沒有執行後面的三句話。這些會在後面的訊號處理中講到,現在不理解沒有關係,這個問題留給大家學習了訊號處理之後來解決。

close(fd); //關閉管道

pause(); /*暫停,等待訊號*/

unlink(fifo); //刪除檔案

}

Linux程序間通訊 管道

linux程序間通訊機制 1.同一主機程序間通訊機制 unix方式 有名管道fifo 無名管道pipe 訊號signal systemv方式 訊號量 訊息佇列 共享記憶體 2.網路通訊 rpc remote procedure call socket 管道管道是程序間通訊中最古老的方式,它包括無名管...

Linux程序間通訊 管道

管道 管道是一種最基本的程序間通訊機制,由pipe函式建立 include intpipe int filedes 2 呼叫pipe函式時在核心中開闢一塊緩衝區 稱為管道 用於通訊,它有乙個讀端乙個寫端,然後通過filedes引數傳出給使用者程式兩個檔案描述符,filedes 0 指向管道的讀端,f...

Linux 程序間通訊 管道

程序間通訊 a程序怎樣將 hello world 傳遞給b程序 i 利用檔案實現 需要乙個 中間人 進行傳遞 檔案 在磁碟中儲存 a先呼叫open函式開啟檔案,再用write函式寫檔案,b用read函式讀取檔案,但問題如下 1.如果a傳送了資料b進行了接收,但a的資料沒有被清空 2.如果a傳送了資料...