程序間通訊筆記(2) 管道和FIFO

2021-07-22 04:27:20 字數 3822 閱讀 6022

管道(pipe):侷限在於沒有名字,只能用於親緣關係的程序使用。

fifo:稱為有名管道(named pipe)

跟套接字程式設計的套路類似,客戶-伺服器回射程式:

這裡客戶從標準輸入(stdin)讀入乙個路徑名,並把它寫入ipc通道。伺服器開啟檔案,讀出其中內容,並寫入ipc通道作為對客戶的響應;客戶將伺服器回射來的內容列印即寫到標準輸出(stdout)。

#include 

int pipe(int fd[2]);

pipe函式建立管道,並提供單向的資料流(不是全雙工哦,如果需要雙向資料流則需要建立兩個管道),該函式返回兩個檔案描述符:fd[0]fd[1]。前者用來讀,後者用來寫。

管道的典型應用是用於父子程序的通訊,父程序建立乙個管道後呼叫fork派生出自己的副本,接著父程序關閉管道的讀出端,子程序關閉寫入端。這樣父子程序間就有了乙個單向的資料流,如下示意:

另外,在shell中使用「|」作為管道命令符,例如:

cat /etc/issue | grep ubuntu
在兩個程序之間建立了乙個管道,通過管道,前乙個程序的標準輸出傳遞給下乙個程序作為標準輸入。

下面實現乙個經典的管道示例,父程序和子程序之間完成通訊,在主程式中建立兩個管道,用於雙向通訊。父程序為客戶,子程序為伺服器,第乙個管道用於客戶向伺服器傳送路徑名,第二個管道用於伺服器向客戶傳送該檔案內容:

通過建立兩個管道實現全雙工的通訊:父程序從標準輸入讀入檔案的路徑名並寫入管道,子程序從管道中讀出檔名並開啟檔案,讀出檔案中的內容寫入管道,父程序從管道中接收檔案中的內容並寫入到標準輸出。

為了方便學習,也是把書中的**解包裹。。。

#include 

#include

#include

#include

#include

#include

#include

#include

#include

void server(int ,int);

void client(int ,int);

const

int maxline = 1024;

int main(int argc,char ** argv)

//父程序

close(pipe1[0]);//關閉讀

close(pipe2[1]);//關閉寫

client(pipe2[0],pipe1[1]);

wait(null);

return0;}

void client(int readfd,int writefd)

len=strlen(buff);

if(buff[len-1]=='\n')

len--;

//路徑名寫入管道

if(write(writefd,buff,len)<0)

//接收檔案中資料,寫入到標準輸出

while((n=read(readfd,buff,maxline))>0)

write(stdout_fileno,buff,n);//stdout_fileno 1 // stdout_fileno=fileno(stdout);

}void server(int readfd,int writefd)

buff[n]='\0';

fd=open(buff,o_rdonly);

if(fd < 0)

//open error 錯誤資訊返回

else

close(fd);}}

fifo類似於管道,它是乙個單向資料流,不同的是,fifo有乙個路徑名與之關聯,從而允許無親緣關係的程序訪問同乙個fifo,fifo也被稱為有名管道(named pipe),使用mkfifo函式可以建立。

#include 

#include

int mkfifo(const

char * pathname,mode_t mode);

//成功返回0 出錯返回-1

不僅僅是函式,我們可以在shell下使用mkfifo建立有名管道。

例如:

***@***: mkfifo mypipe

***@***: echo helloworld > mypipe

在另一終端:

***@***: read line < mypipe

***@***: echo $line

使用fifo讓兩個無親緣關係的程序進行通訊,由於每個fifo有乙個路徑名與之關聯,因此建立fifo後,需要使用i/o函式開啟讀或者開啟寫。

note:fifo不能開啟來既讀又寫,因為它是半雙工的。也就是說o_rdwr這種開啟模式將是未定義的

在使用mkfifo函式的時候,需要注意一些問題:

1.mkfifo是隱含o_creat | o_excl也就是說,該函式要麼建立乙個fifo(成功),要麼返回乙個eexist錯誤(失敗,該fifo已經存在),對於後者來說,它並不妨礙我們繼續使用這個已經存在fifo進行通訊。

2.關於建立的fifo(所關聯的那個檔案),需要說明讀寫許可權,書中給了乙個預設許可權:允許使用者讀寫、組內成員和其他使用者讀,使用掩碼的方式包括起來就是:s_irusr | s_iwusr | s_irgrp | s_iroth

下面就可以實現乙個簡單的生產者消費者了,簡單起見,就只建立乙個fifo完成半雙工的通訊了。

生產者

#include 

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char** argv)

fd = open(pathname,o_wronly, 0);

write(fd,buff,strlen(buff));

return

0;}

消費者
#include 

#include

#include

#include

#include

#include

#include

#include

#include

int main(int argc,char** argv)

fd = open(pathname,o_rdonly, 0);

while( (n = read(fd,readbuff,sizeof(readbuff)))>0 )

return

0;}

1.《unp卷2》

2.

程序間通訊筆記 2

訊號量 訊號量一般配合其他方式一起使用,主要實現程序間的互斥與同步,而不是快取資料。訊號量表示資源的數量,控制訊號量的方式有兩種原子操作 p操作 將這個訊號量減一,減一後如果訊號量小於0代表資源已被占用程序需要阻塞等待。反之表明資源可用可以正常執行。v操作 把訊號量加一,加一後如果訊號量大於等於0代...

程序間通訊 管道和FIFO

程序間通訊 管道和 fifo 管道,顧名思義就是像水管一樣,水管是用來流通水的,而對與管道來說,做為程序間通訊的一種方式,傳送的是資料而已。對於管道來說,沒有名字,在程式內部以識別符號進行識別,這也就注定了管道只能用於有親緣關係的各個程序間使用。但是這一缺點可以通過 fifo 又程為有名管道來彌補,...

程序間通訊 有名管道(FIFO)

1 何謂程序間通訊?多個程序之間資料相互交換稱為程序間通訊。2 程序間通訊的方式都有哪些?1 訊號 2 管道 3 訊號量 4 訊息佇列 5 共享儲存 共享記憶體 6 套接字 訊號在之前的部落格已經講過了,今天重點是說一下管道中的有名管道。3 管道 管道分為兩種 1 半雙工通訊 半雙工通訊是指通訊雙方...