管道檔案是一個特殊的檔案,是由核心環形隊列來實作的。
函數形式: int pipe(int fd[2]) ,無需額外調用open,但需手動調用close來關閉fd[0]和fd[1]。
功能: 該系統調用,用于建立無名管道。無名管道作用于有血緣關系的程序之間,完成資料傳遞。
頭檔案:#include <unistd.h>
參數:兩個檔案描述符,fd[0]是讀端,fd[1]是寫端。
傳回值: 成功傳回0,出錯傳回-1。
特點:
** 管道是建立在記憶體中的,程序結束,空間釋放,管道就不存在了。
** 管道中的資料,讀完後就被删除了。
** 如果管道中沒有資料可讀,則會阻塞。
** 如果管道被寫滿了,也會阻塞。
局限性:
**資料一旦被讀走,便不在管道中存在,不可反複讀取。
**由于管道采用半雙工通信方式。是以,資料隻能在一個方向上流動。
**隻能在有公共祖先的程序間使用管道。
實驗1 - 實作父子程序間通信
實驗思路:
1. 父程序調用pipe函數建立無名管道,得到兩個檔案描述符fd[0]、fd[1]指向管道的讀端和寫端。
2. 父程序調用fork建立子程序,那麼子程序也有兩個檔案描述符指向同一管道。
3. 父程序關閉管道讀端,子程序關閉管道寫端。(這才是正确操作,隻留一個入口,一個出口,這樣才能保證資料隻在一個方向上流動)
父程序可以向管道中寫入資料,子程序将管道中的資料讀出。
由于管道是利用環形隊列實作的,資料從寫端流入管道,從讀端流出,這樣就實作了程序間通信。
實驗代碼:
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
void sys_err(const char *str)
{
perror(str);
exit(1);
}
int main(void)
{
pid_t pid;
char buf[1024];
int fd[2];
char *p = "test for pipe\n";
if (pipe(fd) == -1)
sys_err("pipe");
pid = fork();
if (pid < 0) {
sys_err("fork err");
}else if (pid == 0) {
close(fd[1]);
int len = read(fd[0], buf, sizeof(buf));
write(STDOUT_FILENO, buf, len);
close(fd[0]);
}else {
close(fd[0]);
write(fd[1], p, strlen(p));
wait(NULL); // 不擷取子程序死因,傳入NULL即可。
// 父程序一旦調用了wait就立即阻塞自己,由wait自動分析是否目前程序的某個子程序已經退出。
close(fd[1]);
}
return 0;
}
.
/************* 社會的有色眼光是:博士生、研究所學生、大學生、工廠中的房間勞工; 重點大學高材生、普通院校、二流院校、野雞大學; 年薪百萬、五十萬、五萬; 這些都隻是帽子,可以失敗千百次,但我和社會都覺得,人隻要成功一次,就能換一頂帽子,隻是社會看不見你之前的失敗的帽子。 當然,換帽子決不是最終目的,走好自己的路就行。 杭州.大話西遊 *******/