概述
管道也叫無名管道,它是unix系統ipc(程序間通訊)的最古老形式,所有的unix系統都支援這種通訊機制
特點
雙半工,資料在同一時刻只能在乙個方向上流動
資料只能從管道一端寫入,從另一端讀出
寫入管道中的資料遵循先入先出的規則
管道所傳送的資料是無格式的,這要求管道的讀出方與寫入方要事先約定好資料格式,如多少位元組算乙個訊息等
管道不是普通檔案,不屬於某個檔案系統,只存在於記憶體中
管道在記憶體中對應乙個緩衝區,不同的系統大小不一定相同
管道讀資料是一次性操作,資料一旦被讀走,它就從管道中被拋棄,釋放空間以便寫入更多資料
管道沒有名字,只能在具有公共祖先的程序(父程序與子程序,或兩個兄弟程序,具有親緣關係)之間使用
管道是一種特殊的檔案,在應用層體現為兩個開啟的檔案描述符
pipe 函式
#includeint pipe(int pipefd[2]);
// 功能 建立無名管道
// 引數 pipefd[2] int 型別陣列 用來存放管道檔案描述符
// 當乙個管道建立時,會建立兩個檔案描述符 fd[0] 和 fd[1]。 其中 fd[0] 固定用於讀管道
// fd[1] 固定用於寫管道,一般檔案i/o函式都可以用來操作管道(lseek 不行)
// 返回值 成功 0 失敗 -1
// pipe.c
#include#include#includeint main()
printf("fds[0] %d fds[1] %dn",fds[0],fds[1]);
close(fds[0]);
close(fds[1]);
return 0;
}// 編譯 gcc pipe.c -o pipe
// 執行 ./pipe 結果如下圖
父子程序通過無名管道通訊
// pipe2.c
#include#include#include#include#define size 64
int main()
//建立子程序
pid=fork();
if(-1 == pid)
//子程序讀管道
if(0==pid)
printf("fork read %sn",buf);
close(fds[0]);//關閉讀端
exit(0);//子程序退出
} //父程序寫管道
close(fds[0]);//關閉讀端
ret=write(fds[1],"abc123",6);
if(ret<0)
printf("main write len %dn",ret);
close(fds[1]);//關閉寫端
return 0;
}// 編譯 gcc pipe2.c -o pipe2
// 執行 ./pipe2 結果如下
管道的讀寫特點
讀管道管道中有資料 read返回實際讀到的位元組數
管道中無資料 寫端被全部關閉 read 返回 0,寫端沒有全部關閉 read 阻塞等待
寫管道管道讀端全部關閉 程序異常終止(也可使用捕捉sigpe訊號,使程序終止)
管道讀端沒有全部關閉 管道己滿 write阻塞,管道未滿 write 將資料寫入 並返回實際寫入位元組數
設定管道為非阻塞
int flags=fcntl(fd[0],f_getel);
flag |= o_nonblock;
fcntl(fd[0],f_setfl,flags);
// pipe4.c
#include#include#include#include#include#define size 64
int main()
//建立子程序
pid=fork();
if(-1 == pid)
//子程序讀管道
if(0==pid)
printf("fork read %sn",buf);
close(fds[0]);//關閉讀端
exit(0);//子程序退出
} sleep(3);
//父程序寫管道
close(fds[0]);//關閉讀端
ret=write(fds[1],"abc123",6);
if(ret<0)
printf("main write len %dn",ret);
close(fds[1]);//關閉寫端
return 0;
}// 編譯 gcc pipe4.c -o pipe4
// 執行 ./pipe4 結果如下
// 子程序中的讀設定為非阻塞,沒有等父程序去寫,就立馬返回 就報錯了
// 父程序沒寫是因為讀端己經關閉,直接異常終止了
檢視管道大小
ulimit -a
# 512位元組 * 8
用c語言中的函式檢視
#includelong fpathconf=(int fd,int name);
// 功能 通過name 引數檢視不同屬性值
// 引數 fd 管道檔案描述符
// name _pc_pipe_buf 檢視管道緩衝區大小, _pc_name_max 位元組數上限
// 返回值 功能 返回對應資料, 失敗 返回 -1
// pipe3.c
#include#include#include#includeint main()
// 編譯 gcc pipe3.c -o pipe3
// 執行 ./pipe3
// 結果如圖
linux管道(無名管道)
首先管道是程序之間的乙個單向資料流,它的資料流向由核心管理,只能從乙個程序流向另外乙個程序,乙個程序向管道寫入資料,另外乙個程序從這個管道讀取資料。在使用管道 無名管道 時,只能用在父子程序或者親屬程序之間,若要用在任意程序之間則需要使用fifo 有名管道 如圖程序ab通過管道進行資料交換。程序a通...
Linux管道(無名管道)
是一套免費使用和自由傳播的類unix作業系統,是乙個基於posix和unix的多使用者 多工 支援多執行緒和多cpu的作業系統。它能執行主要的unix工具軟體 應用程式和網路協議。它支援32位和64位硬體。linux繼承了unix以網路為核心的設計思想,是乙個效能穩定的多使用者網路作業系統。它主要用...
無名管道和有名管道
無名管道 無名管道建立 int pipe int filedis 2 當乙個管道建立時,它會建立兩個檔案描述符 filedis 0 用於讀管道,filedis 1 用於寫管道 管道用於不同程序間通訊。通常先建立乙個管道,再通過fork函式建立乙個子程序,該子程序會繼承父程序所建立的管道 有名管道 有...