APUE筆記 進程間通信

管道

#include <unistd.h>

int pipe(int fds[2]);

fd返回兩個文件描述符,fd[0]讀,fd[1]寫!

管道是單雙工的,只能一端寫,另一端讀,不能兩邊同時讀寫

管道實際上是在,內核中開闢了一個循環隊列,

當隊列寫滿(隊空)時,繼續寫(讀)管道會阻塞當前進程!

當寫端關閉,繼續讀時返回EOF

當讀端關閉,繼續寫時候發送SIGPIPE信號,默認關閉進程


可能多個進程往管道寫,若指定寫的字節數< 管道空間大小PIP_BUF,則寫數據不會交叉(獨佔寫,寫是院子操作)

                                            若指定寫的字節數> 管道空間大小PIP_BUF,則寫數據可能會交叉(寫滿管道,阻塞,管道有空間,大家一起競爭寫?)                                           


pipe創建的管道只能用於有親緣關係的進程間通信,父進程創建管道,fork子進程繼承文件描述符,則可以父進程用fd[0]讀,子進程從fd[0]寫!

爲確保,讀寫單向,讀端應該關閉寫fd[1],寫端關閉讀fd[0]



popen& pclose

 #include <stiod.h>

FILE *popen(const char *cmdstr, const char *type);

int pclose(FILE *fp);

open 開一個管道,然後調用fork,使用exec執行cmdstr 命令

返回一個標準I/O流,type 爲“r”返回標準讀,“w”返回標準寫即fd綁定爲fd[1]

注意,因爲管道作爲標準輸入/出,所以默認使用全緩衝,可能造成讀不到,或者寫不到數據

在讀寫之前追號設置俄爲行緩衝!


              管道可在程序設計時候,作爲中間處理代碼,插入某一個流程,作爲中間處理!


FIFO

管道只能用於親緣關係的進程之間通信

FIFO可以用於無關係的進程間通信

可在磁盤中中創建一個文件,管道的inode會指向內核空間的,管道內存(循環隊列)

文件的實際大小是0

通過文件所有的進程就都能索引到管道的實際內容!


#include <sys/stat.h>

int mkfifo(const char *path, mode_t mode);

int mkfifoat(int fd, const char *path, mode_t mode );

創建一個FIFO文件,通過S_ISFIFO可以判斷是否文FIFO文件


open未指定O_NOBLIOCK(默認),讀(寫)打開,無進程以寫(讀)打開時,阻塞,知道有進程以寫(讀)打開


FIFO可以用來實現服務進程/客戶進程的模型

客戶以公用管道寫,大小應小於PIPE_BUF 以保證寫操作的原子性

服務以私有管道寫,客戶從此管道讀(注意處理SIGPIPE,客戶進程可能以外終止)


shell 用來將數據從一條管道送到另一條管道,無須臨時文件???


                                                               














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章