← 返回首页
Linux高级程序设计(四十六)
发表时间:2021-11-28 14:55:15
pipe函数

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() 函数从管道中读数据是阻塞的。