管道(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進行通訊。下面就可以實現乙個簡單的生產者消費者了,簡單起見,就只建立乙個fifo完成半雙工的通訊了。2.關於建立的fifo(所關聯的那個檔案),需要說明讀寫許可權,書中給了乙個預設許可權:允許使用者讀寫、組內成員和其他使用者讀,使用掩碼的方式包括起來就是:
s_irusr | s_iwusr | s_irgrp | s_iroth
生產者
#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 半雙工通訊 半雙工通訊是指通訊雙方...