c pipe 管道 c 筆記 無名管道

2021-10-18 11:13:57 字數 3421 閱讀 9910

概述

管道也叫無名管道,它是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函式建立乙個子程序,該子程序會繼承父程序所建立的管道 有名管道 有...