##管道基礎
#通信分類:只寫單工管道、只讀單工管道削锰、半雙工管道(單向讀寫)妹卿、全雙工管道(兩個半雙工管道拼接)
類型 創(chuàng)建/打開 關閉 讀 寫
單工 popen() pclose() read() write()
半雙工 pipe()/open() close() read() write()
FIFO半雙工 mkfifo()/open() close()/unlink() read() write()
全雙工 socketpair() close() read() write()
管道通常用于進程間通信熄求,可以用KFC買東西來比喻渣玲,通過man 7 pipe來查看管道在redhat中的官方解釋。
#管道的分類
@匿名管道
特點:必須是親緣進程之間
案例:
ps_self \\打印自身的父子進程信息
ps_other \\執(zhí)行參數中的命令抡四,并且打印參數中的命令相關的父子進程
分類:
*單工管道
操作: 管道 文件
打開 popen() fopen()
關閉 pclose() pclose()
打開管道:FILE* popen(const char* command,const char* open_mode);
command:命令行字符串
open_mode:只讀"r"柜蜈;只寫"w"
返回值:文件描述符 NULL(打開失斦套弧)
讀寫:
size_t fread(void* buffer,size_t size,size_t count,FILE* stream)
buffer:用于接收數據的內存地址
size:讀取每個數據項的字節(jié)數
count:數據項個數
stream:輸入流
返回值:出錯(>count)指巡、整數(實際讀取的數據項個數)
size_t fwrite(const void* buffer,size_t size,size_t count,FILE* stream)
buffer:寫入數據的內存地址
size:寫入數據項的字節(jié)數
count:寫入數據項的個數
stream:目標文件指針
返回值:出錯(>count)淑履、正數(實際寫入的數據項個數)
關閉管道:int pclose(FILE* stream);
stream:文件描述符
返回值:失敗(-1)藻雪、成功(0)
本質:
a.啟動shell和命令兩個進程秘噪,從命令進程中讀/寫文件流
b.解決exec和system無法返回輸出數據問題
特點:
a.方便使用系統(tǒng)自帶功能,并且可以執(zhí)行比較復雜shell
b.默認啟動兩個進程勉耀,效率較低
*半雙工管道
操作:
創(chuàng)建管道:int pipe(int filedes[2])
filedes[0] 讀
filedes[1] 寫
返回值:失斨讣濉(-1)、成功(0)
讀寫
ssize_t write(int fd,const void* buf,size_t nbyte)
fd:文件描述符
buf:寫入數據的內存單元
nbyte:寫入文件指定的字節(jié)數
返回值:出錯(-1)便斥、正數(寫入的字節(jié)數)
ssize_t read(int fd,void* buf,size_t count)
fd:文件描述符
buf:讀入數據的內存單元
返回值:出錯(-1)至壤、0(無數據)、正數(讀取的字節(jié)數)
控制:如果管道是空的枢纠,read()默認是阻塞
int fcntl(int fd,int cmd,long arg)
fd:文件描述符
cmd:F_GETFL(獲取文件描述符狀態(tài))像街、F_SETFL(設置文件描述符狀態(tài))、……
arg:O_NONBLOCK(非阻塞)晋渺、O_BLOCK(阻塞)镰绎、……
fcnt(filedes,F_SETFL,O_NONBLOCK); \\把文件描述符改為非阻塞的。
關閉管道:close(filedes)
本質:文件描述符[文件流是文件描述符之上的封裝木西。文件流通過增加緩沖區(qū)減少讀寫系統(tǒng)調用次數來提高讀寫效率畴栖。在進程的用戶空間封裝的FILE結構,以提高可移植性和效率]
*復制管道
定義:Linux內核使用三個關聯(lián)的數據結構八千,表示打開的文件吗讶。【描述符表恋捆,文件表照皆,v-node表】內核為每個進程創(chuàng)建的文件文件描述符。
分類 文件描述符 文件號
標準輸入 STDIN_FILENO 0
標準輸出 STDOUT_FILENO 1
標準出錯信息 STDERR_FILENO 2
int dup(oldfd) \\返回值:-1(失旔拧)纵寝、其他(新的文件描述符)
int dup2(int oldfd,int newfd) \\返回值:-1(失敗)星立、其他(最小及尚未使用的文件描述符)
@【半雙工】FIFO管道/命名管道
特點:可以是非親緣進程之間爽茴;讀寫必須同時執(zhí)行,否則阻塞绰垂。
案例:FIFO工具箱
操作:
創(chuàng)建命名管道:int mkfifo(pathname,mode)【古老方式:int mknod(const char *filename,mode_t mode | S_IFIFO,(dev_t)0);】
pathname:文件路徑【文件必須不存在】
mode:模式
返回值:0(成功)室奏、非零(失敗)
打開FIFO文件:int open(const char* path,int mode)
pathname:文件路徑
mode:模式【O_RDONLY(阻塞只讀)劲装、O_RDONLY|O_NONBLOCK(非阻塞只讀)胧沫、O_WRONLY(阻塞只寫)昌简、O_WRONLY|O_NONBLOCK(非阻塞只寫)】
返回值:-1(失敗)绒怨、其他(文件描述符)