pipe函数用来创建无名管道。
1.函数原型
#include <unistd.h>
int pipe(int fd[2]);
它由输出型参数fd返回两个文件描述符,fd[0]为读而打开,fd[1]为写而打开,fd[1]的输出是fd[0]的输入,当管道创建成功后pipe函数返回0,如果创建失败则返回-1。
实例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <string.h>
int main(int argc, char *argv[])
{
int fd_pipe[2];
if(pipe(fd_pipe)==-1){
perror("error to create pipe:");
exit(1);
}
printf("fd_pipe[0]=%d\n",fd_pipe[0]);
printf("fd_pipe[1]=%d\n",fd_pipe[1]);
if(write(fd_pipe[1],"hello,world!",12)==-1){
perror("error to write:");
exit(1);
}
write(fd_pipe[1],"hello,linux!",strlen("hello,linux!"));
char buff[32]="";
int bytes=-1;
if((bytes = read(fd_pipe[0],buff,sizeof(buff)))==-1){
perror("error to read:");
exit(1);
}
printf("buff=%s\n",buff);
printf("bytes=%d\n",bytes);
//再次读取会进入阻塞状态
if((bytes = read(fd_pipe[0],buff,sizeof(buff)))==-1){
perror("error to read:");
exit(1);
}
printf("buff=%s\n",buff);
printf("bytes=%d\n",bytes);
return 0;
}
运行结果:
[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
fd_pipe[0]=3
fd_pipe[1]=4
buff=hello,world!hello,linux!
bytes=24
2.管道的特点
每个管道只有一个页面作为缓冲区,该页面是按照环形缓冲区的方式来使用的。这种访问方式是典型的“生产者——消费者”模型。当“生产者”进程有大量的数据需要写时,而且每当写满一个页面就需要进行睡眠等待,等待“消费者”从管道中读走一些数据,为其腾出一些空间。相应的,如果管道中没有可读数据,“消费者” 进程就要睡眠等待,具体过程如下图所示:

默认的情况下,从管道中读写数据,最主要的特点就是阻塞问题(这一特点应该记住),当管道里没有数据,另一个进程默认用 read() 函数从管道中读数据是阻塞的。