每個程序各自有不同的使用者位址空間,任何乙個程序的全域性變數在另乙個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序a把資料從使用者空間拷到核心緩衝區,程序b再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊。
不同程序間的通訊本質:程序之間可以看到乙份公共資源;而提供這份資源的形式或者提供者不同,造成了通訊方式不同,而 pipe就是提供這份公共資源的形式的一種。
管道是由呼叫pipe函式來建立
#include
int pipe (int fd[2]);
//返回:成功返回0,出錯返回-1
fd引數返回兩個檔案描述符,fd[0]指向管道的讀端,fd[1]指向管道的寫端。fd[1]的輸出是fd[0]的輸入。
(1)父程序建立管道,得到兩個⽂件描述符指向管道的兩端
(2)父程序fork出子程序,⼦程序也有兩個⽂件描述符指向同⼀管道。
(3)父程序關閉fd[0],子程序關閉fd[1],即⽗程序關閉管道讀端,⼦程序關閉管道寫端(因為管道只支援單向通訊)。⽗程序可以往管道⾥寫,⼦程序可以從管道⾥讀,管道是⽤環形佇列實現的,資料從寫端流⼊從讀端流出,這樣就實現了程序間通訊。
}
執行結果:
每隔2秒列印一次i am child! 並且列印了五次。
(1)讀端不讀,寫端一直寫
(2)寫端不寫,但是讀端一直讀
(3)讀端一直讀,且fd[0]保持開啟,而寫端寫了一部分資料不寫了,並且關閉fd[1]。
如果乙個管道讀端一直在讀資料,而管道寫端的引⽤計數⼤於0決定管道是否會堵塞,引用計數大於0,唯讀不寫會導致管道堵塞。
(4)讀端讀了一部分資料,不讀了且關閉fd[0],寫端一直在寫且f[1]還保持開啟狀態。
} //寫方還在繼續,而讀方已經關閉它的讀端
close(fd[0]);
pid_t ret = waitpid(id, &status, 0);
printf(」exitsingle(%d),exit(%d)\n」, status & 0xff, (status >> 8) & 0xff);
//低八位存放該子程序退出時是否收到訊號
//此低八位子程序正常退出時,退出碼是多少
} else
return 0;
} 執行結果:
使用kill -l 檢視13號訊號,可以知道13號訊號代表sigpipe。
總結: 如果乙個管道的寫端一直在寫,而讀端的引⽤計數是否⼤於0決定管道是否會堵塞,引用計數大於0,只寫不讀再次呼叫write會導致管道堵塞; 如果乙個管道的讀端一直在讀,而寫端的引⽤計數是否⼤於0決定管道是否會堵塞,引用計數大於0,唯讀不寫再次呼叫read會導致管道堵塞; 而當他們的引用計數等於0時,只寫不讀會導致寫端的程序收到乙個sigpipe訊號,導致程序終止,只寫不讀會導致read返回0,就像讀到⽂件末尾⼀樣。
1.管道只允許具有血緣關係的程序間通訊,如父子程序間的通訊。
2.管道只允許單向通訊。
3.管道內部保證同步機制,從而保證訪問資料的一致性。
4.面向位元組流
5.管道隨程序,程序在管道在,程序消失管道對應的埠也關閉,兩個程序都消失管道也消失。
測試管道容量大小只需要將寫端一直寫,讀端不讀且不關閉fd[0],即可。
測試**:
#include
#include
#include
#include
int main()
pid_t id = fork();
if (id == 0)
close(fd[1]);
}else
if (id>0)
else
return
0;}
可以看到寫到65520之後管道堵塞了,而65520即為64k大小即為管道的容量。
程序間通訊方式———訊號量(semaphore)
程序間通訊方式———訊息佇列
程序間通訊方式——共享記憶體
Linux下程序間通訊方式 pipe(管道)
每個程序各自有不同的使用者位址空間,任何乙個程序的全域性變數在另乙個程序中都看不到,所以程序之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,程序a把資料從使用者空間拷到核心緩衝區,程序b再從核心緩衝區把資料讀走,核心提供的這種機制稱為程序間通訊。不同程序間的通訊本質 程序之間可以看到乙份公共資源...
程序間的通訊方式 pipe(1 管道)
程序通訊就是兩個程序之間進行資料交換,在linux中有好幾種可以進行程序通訊的方式,在這篇文章中我們主要介紹最基本的程序通訊方式 pipe管道。程序之間交換資訊的唯一途徑就是傳送開啟的檔案。管道是一種最古老也是最基本的系統ipc形式,所有的linux系統都提供此種通訊機制。但是管道有以下兩個侷限性 ...
程序間通訊(IPC) 管道(Pipe)
管道 乙個程序連線資料流到另乙個程式 pipe函式的原型 include int pipe int file descriptor 2 該閃身在陣列中填上兩個新的檔案描述符後返回0,如果失敗則返回 1。寫到file descriptor 1 的所有資料都可以從file descriptor 0 讀回...