进程间通信——管道

前言

进程间通讯就是在两个进程之间传递数据

进程间通讯机制(ipc):管道,信号量,消息队列,共享内存,套接字

一、管道文件

(写入管道的数据存放在内存中。)

1.1管道文件

管道的使用需要在两个进程,一个往管道写入数据,一个从管道读取数据;
管道为空,写端阻塞,管道写满,写端阻塞
使用管道只能读或者写,数据流都是单向的,如果需要双向的,则需要多创建管道

1.写端关闭,读端int n = ead返回值为,写入数据的进程停止运行,读取数据的进程也随之结束;
2.读端关闭,写端write会触发信号SIGPIPE,读取数据的进程先结束,系统会给写入数据的进程发送信号,将其终止。

在这里插入图片描述

分类:
有名管道:可以在任意两个进程之间进行通信(需要两个进程同时打开才可以)
无名管道:只能在父子进程之间使用

二、有名管道

有名管道可以在任意两个进程之间通信
有名管道的创建:
◼ 命令创建: mkfifo FIFO(创建一个名为FIFO的管道文件)
◼ 系统调用创建

//头文件以及函数介绍
 #include <sys/types.h>
 #include <sys/stat.h>

 //filename 是管道名 mode 是创建的文件访问权限
 int mkfifo(const char *filename, mode_t mode);

使用
1.创建一个往管道写入数据的a.c文件

   #include<stdio.h>
   #include<assert.h>
   #include<string.h>
   #include<unistd.h>
   #include<stdlib.h>
   #include<fcntl.h>
   
   int main()
   {
      int fdw = open("fifo",O_WRONLY);
      assert(fdw != -1);//fwd > 0,   3
  
      printf("fdw = %d\n",fdw);
      char buff[128] = {0};
      while(1)
      {
      fgets(buff,128,stdin);
  
      write(fdw,buff,strlen(buff));
  
      if(strncmp(buff,"end",3) == 0)
      {
          break;
      }
      }
      close(fdw);
  }

2.创建一个从管道读取数据的b.c文件

   #include<stdio.h>
   #include<assert.h>
   #include<string.h>
   #include<unistd.h>
   #include<stdlib.h>
   #include<fcntl.h>
   
   int main()
   {
      int fdr = open("fifo",O_RDONLY);
      assert(fdr != -1);//fwd > 0,   3
  
      printf("fdr = %d\n",fdr);
      while(1)
      {
      char buff[128] = {0};
      int n = read(fdr,buff,127);
      if(n < 0 || strncmp(buff,"end",3) == 0)
      {
          break;
      }
      printf("buff = %s\n",buff);
      }
      close(fdr);
  }

3.编译链接a.c,b.c,同时运行a,b
在这里插入图片描述
a写入,b读取
在这里插入图片描述
a输入“end”结束
在这里插入图片描述

三、无名管道

无名管道主要应用于父子进程间的通信。
无名管道的创建:

//头文件以及函数介绍
 #include <unistd.h>
 /*
 pipe()成功返回 0,失败返回-1
 fds[0]是管道读端的描述符
 fds[1]是管道写端的描述符
 */
 int pipe(int fds[2]);

使用

   #include<stdio.h>
   #include<assert.h>
   #include<string.h>
   #include<unistd.h>
   #include<stdlib.h>
   #include<fcntl.h>
   
   int main()
   {
      int fd[2]; //fd[0] 只读,fd[1] 只写
      int res = pipe(fd);//创建管道,得到读写描述符
      assert(res !=  -1);
  
      pid_t pid = fork();
      assert(pid != -1);
  
      if(pid == 0)
      {
          close(fd[1]);
          char buff[128] = {0};
          read(fd[0],buff,127);
          printf("child read : %s\n",buff);
          close(fd[0]);
      }
      else
      {
          close(fd[0]);
          write(fd[1],"hello",5);
          close(fd[1]);
      }
      exit(0);
  }

运行结果:child read : hello

总结

1.有名管道 无名管道 区别?
有名管道可以在任意两个进程之间通信,无名管道只能在父子进程见使用

2.写入管道的数据存放在哪里?
内存中

3.管道是一个半双工的通信方式。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

__小柒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值