- 1、函数介绍
- 2、需求,代码
1、pipe函数,创建并打开管道
int pipe(int pipefd[2]);
参数:
fd[0] 读端
fd[1] 写端
返回值:
成功 0
失败 -1 errno
2、需求,代码
创建管道(必须有血缘关系进程才能通信),之后使用fork创建子进程,使用dup2重定向,execlp执行命令写入管道写端,子进程使用dup2,改变读的位置,执行execlp
#include#include #include #include void sys_err(const char* str) { perror(str); exit(1); } int main(int argc,char* argv[]) { int ret; int fd[2]; ret = pipe(fd); // 创建进程 if(ret==-1) { sys_err("pipe error"); } pid_t p = fork(); if(p>0) { close(fd[0]); //关闭读端 // 将输出到屏幕的文件描述符,重定向到管道写端 dup2(fd[1],STDOUT_FILENO); // 默认ls命令是,写到屏幕,由于上面的重定向,现在写道管道了 execlp("ls","ls",NULL); // 上面成功,这条不会执行,这里我们只能先依赖系统回收,后面使用信号回收 close(fd[1]); } else if(p==0) { close(fd[1]); //关闭写端 // 将输入文件描述符,重定向到读端 dup2(fd[0],STDIN_FILENO); // wc默认是读取屏幕内容,现在从管道的读端读取 execlp("wc","wc","-l",NULL); // 上面成功,这条不会执行,这里我们只能先依赖系统回收,后面使用信号回收 close(fd[0]); } return 0; }
3、 管道注意事项
管道的原理:管道实为内核使用环形队列机制,借助内核缓冲区(4096)实现
管道的局限性:
1、数据不能进程自己写,自己读
2、管道中数据不可反复读取,一旦读走,管道中不在存在
3、采用半双通信方式,数据只能在单方向上流动
管道的读写行为:
读管道:
1、管道有数据,read返回实际读到的字节数
2、管道无数据:
无写端,read返回0(读到文件结尾)
有写端,read堵塞等待
写管道:
无读端,异常终止,(SIGPIPE导致的)
有读端:
管道已满,阻塞等待
管道未满,返回写出的字节个数



