进程间通信(一)匿名管道

  • 进程间通信的目的
    数据传输:一个进程将他的数据发送给另外一个进程
    资源共享:多个进程之间共享同样的资源
    通知事件:一个进程需要向另一个或者另一组进程发送信息,通知他们发生了某件事
    进程控制:有些进程希望完全控制另一个进程的执行,此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道他的状态改变。

  • 进程间通信
    进程间为什么需要沟通交流?
    在实际工作中往往会出现一个系统中好几个进程协同工作,那么这些进程就需要交流沟通才能完成协助。
    因为进程的独立性,因此进程间沟通就变得困难,复杂。因此产生了进程的通信方式,来解决进程如何通信的问题。

  • 进程间通信的发展
    管道:管道是UNIX中最古老的进程间通信方式。
    我们把从一个进程连接到另一个进程的数据流称为管道
    这里写图片描述
    管道有一个很重要的特点:单向通信(它本质上是一块内核的缓冲区
    操作系统为管道提供的方法是:文件操作

  • 管道的读写规则
    1.当没有数据可读时:
    O_NONBLOCK disable:read 调用阻塞,进程暂停执行,直到有数据来为止。(就像水管里没有水,只有等待水来了才能接水)
    O_NONBLOCK enable:read 调用返回-1,errno值为EAGAIN.
    2.当管道满了时:
    O_NONBLOCK disable:write调用阻塞,直到有进程读走数据
    (就像水管里水是满的,只有你接走了水管里的水,水管才能进入新的水)
    O_NONBLOCK enable:调用返回-1,errno值为ENGAIN.

  • 匿名管道的特点
    1.只能用于有共同祖先或者亲缘关系的进程,通常一个管道由一个进程创建,然后该进程调用fork函数,之后父子进程就可以使用该管道。
    2.管道提供流式服务
    3.管道的生命周期跟随进程终止
    4.管道是半双工的,数据只能向一个方向流动,需要数据互通时需建立两个管道。
    5.管道是面向字节流传输数据的:
    面向字节流:收发数据比较灵活,数据无规则发送,数据无边界。
    面向数据报:数据只能整条接收
    6.管道自带同步与互斥
    临界资源:大家都能访问的公共资源
    临界区:对临界资源进行操作的代码
    同步:访问的可控时序性
    互斥:对临界资源的同一时间内唯一访问性(保护临界资源的安全)
    这里写图片描述

  • 管道的分类:匿名管道/命名管道
    1.匿名管道:仅用于具有亲缘关系的进程通信
    这里写图片描述
    这里写图片描述

示例代码:

  //这是一个匿名管道的实现,功能:父进程写入数据,子进程读取打印数据
  //int pipe(int pipefd[2])
  //pipefe:用于接收匿名管道创建成功后返回的两个描述符
  //这是一个匿名管道的实现,功能:父进程写入数据,子进程读取打印数据
  //int pipe(int pipefd[2])
  //pipefe:用于接收匿名管道创建成功后返回的两个描述符
  //pipefd[0]用于从管道读取数据
  //pipefd[1]用于从管道写入数据
  //  成功返回0, 失败返回-1
  //匿名管道仅用于具有亲缘关系的进程通信
  #include<stdio.h>
  #include<unistd.h>
  #include<string.h>
  #include<stdlib.h>
  #include<errno.h>
   int main()
  {
      int fd[2];//管道需要在创建子进程之前创建好,才能复制
      if(pipe(fd)<0){
      perror("pipe error");
          return -1;
      }
      int pid=-1;
      pid=fork();//创建子进程
      if(pid<0)return -1;//当pid小于0时,进程创建失败
      else if(pid==0){//子进程内读取数据
          //子进程读取数据
          close(fd[1]);//因为是读取数据所以关闭fd【1】
          char buff[1024]={0};
          read(fd[0],buff,1024);//读取buff中存的字符串
          printf("child: %s\n",buff);//打印字符串
          close(fd[0]);//读取完毕关闭fd【0】
      }else{//父进程内写入数据
          close(fd[0]);//因为是写入数据,所以关闭fd[0]
          write(fd[1],"hello",5);//写入hello,5个字符
          close(fd[1]);//写入完毕,关闭fd【1】
      }
      return 0;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值