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 用来将数据从一条管道送到另一条管道,无须临时文件???


                                                               














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