进程间通信之无名管道PIPE

1. 无名管道函数接口

通常说的管道通常指无名管道(PIPE)、有名管道(FIFO),但实际上Socket也是管道,这里我们先介绍下无名管道,我们先把无名管道的函数接口列出来

创建无名管道的函数接口规范

功能描述其它
头文件#include <unistd.h>/
原型int pipe(int pipefd[2]);/
参数pipefd一个至少具有2个int型数据的数组,用来存放PIPE的读/写端描述符
返回值成功返回0失败返回-1

2. 无名管道PIPE特性

 先来看PIPE,既然叫管道,那么可以想象它就像一根水管,连接两个进程,一个进程给另一个进程数据,就好像将水灌进管道一样,另一端就可以取出来了。反过来也一样。

先来罗列以下PIPE的特性

  1. 没有名字,因此无法使用open()
  2. 只能用于亲缘进程间(如父子进程、兄弟进程、祖孙进程)通信
  3. 半双工工作方式:PIPE不同于一般文件描述符的的显著之处:它有两个文件描述符,而不是一个!一个只能用来写,另一个只能用来读,这就是所谓的半双工通信方式
  4. 写入操作不具有原子性,因此只能用来一对一的简单通信的情景
  5. 不能使用lseek()来定位,因为管道文件不像普通文件那样可以按块的方式存放在硬盘上、Flash等设备上,更像一个看不见源头的水龙头,无法定位

PIPE是一种特殊的文件,虽然它是一种文件,但是却没有名字!因此一般的进程无法通过open()来获取它的文件描述符,它只能在一个进程中被创建出来,然后通过继承的方式将它的文件描述符传递给子进程,这就是为什么PIPE只能用于亲缘进程间通信的原因

3. 无名管道PIPE管道示例

以下代码展示了子进程如何通过PIPE向父进程发送一段数据。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <error.h>

int main(int argc, char **argv){
    
    int fd[2];              //用来存放PIPE的两个文件描述符
    if(-1 == pipe(fd)){     //创建PIPE,并将文件描述符存放在fd数组中 
        perror("pipe()");
        exit(1);
    }

    pid_t pid = fork();    //创建一个子进程,它将会继承PIPE的描述符,fork一次会有两次返回
    if(pid < 0){
        perror("fork()");
        exit(1);
    }

    if(0 == pid){           //子进程返回时pid == 0
        close(fd[0]);        //关闭读端
        char *s = "Hello World!\n";
        write(fd[1], s, strlen(s));     //通过写端fd[1]将数据写入到PIPE中
    }

    if(pid > 0){            //父进程返回时pid > 0, 此时pid为子进程的进程号  
        close(fd[1]);       //关闭写端
        char buff[30];
        bzero(buff, 30);
        read(fd[0], buff, 30);  //通过读端fd[0]将数据从PIPE中读出来
        printf("read buffer from child: %s\n", buff);
    }

    close(fd[0]);
    close(fd[1]);
    return 0;
}

  任何事物的优缺点都是相对的,PIPE简单,但适用场景比较单一、性能较弱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

博可睿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值