重要概念!!!

进程间通信(IPC,InterProcess Communication)是指在不同进程之间传播或交换信息。

IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。其中 Socket和Streams支持不同主机上的两个进程IPC。

管道

管道,顾名思义,是进程之间数据流输入输出的通道,我们称pipe管道,通常是把一个进程的输出通过管道连接到另一个进程的输入。管道又分为两种:无名管道(也就是我们说的管道)和FIFO(又称命名管道),FIFO和管道都是半双工,单向的数据通信。接下来看看二者有怎样的异同点。

管道(无名管道)

管道,通常指无名管道,是 UNIX 系统IPC最古老的形式。

特点:

  1. 它是半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。

  2. 它只能用于具有亲缘关系的进程之间的通信(也是父子进程或者兄弟进程之间)。

  3. 它可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write 等函数。但是它不是普通的文件,并不属于其他任何文件系统,并且只存在于内存中。

原型:

NAMEpipe, pipe2 - create pipeSYNOPSIS#include <unistd.h>int pipe(int pipefd[2]);

返回值:
若成功返回0

失败返回-1


当一个管道建立时,它会创建两个文件描述符fd[0]和d[1],其中fd[0]为读而打开,fd[1]为写而打开,关闭管道只需将这两个文件描述符关闭即可。

单个进程中的管道几乎没有任何用处。所以,通常调用 pipe 的进程接着调用 fork,这样就创建了父进程与子进程之间的 IPC 通道。

若要数据流从父进程流向子进程,则关闭父进程的读端(fd[0])与子进程的写端(fd[1]);反之,则可以使数据流从子进程流向父进程。

如下爬的图:

看看这个demo:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>int main(){//int pipe(int pipefd[2]);int fd[2];pid_t pid;char *buf = "hello from father";   char readBuf[128];if(pipe(fd) == -1){ printf("create pipe failed!\n");}pid = fork();if(pid < 0){printf("fork failed!\n");}else if(pid > 0){    sleep(3);   printf("this is father\n");close(fd[0]);
//      ssize_t write(int fd, const void *buf, size_t count);write(fd[1],buf,strlen(buf));wait();}else{printf("this is child\n");close(fd[1]);
//      ssize_t read(int fd, void *buf, size_t count);read(fd[0],readBuf,strlen(buf));
//      printf("%s\n",readBuf);printf("%s\n",readBuf);exit(0);}return 0;
}

我们通过pipe创建管道,搭配fork使用,使用fork就说明父进程和子进程是依据系统调度进行的,不知道哪个先哪个后,所以当先执行子进程时,readbuf里面没有数据,会自己阻塞,将资源分配给父进程,父进程中write之后再去子进程中read

这里注意的是,我们在读的时候要关闭写,在写的时候要关闭读,如下图

FIFO(命名通道)

FIFO,也称为命名管道,它是一种文件类型。

特点:

  1. FIFO可以在无关的进程之间交换数据,与无名管道不同。

  2. FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中。(这里是特殊的设备文件形式,而管道是存在内存中。。注意区别)

原型:

NAMEmkfifo - make a FIFO special file (a named pipe)SYNOPSIS#include <sys/types.h>#include <sys/stat.h>int mkfifo(const char *pathname, mode_t mode);

pathname就是文件路径, mode 参数与open函数中的 mode 相同(可以看看里面的open函数mode学习笔记——Linux的open、write、read、lseek、close函数)。一旦创建了一个 FIFO,就可以用一般的文件I/O函数操作它。

返回值

成功返回0
出错返回-1

当 open 一个FIFO时,是否设置非阻塞标志(O_NONBLOCK)的区别:

若没有指定O_NONBLOCK(默认),只读 open 要阻塞到某个其他进程为写而打开此 FIFO。类似的,只写 open 要阻塞到某个其他进程为读而打开它。可以理解为,我这边的只读进程阻塞了,进行不下去了,需要另一个只写进程来配合打开FIFO。

若指定了O_NONBLOCK,则只读 open 立即返回。而只写 open 将出错返回 -1 如果没有进程已经为读而打开该 FIFO,其errno置ENXIO。

我们看看demo是怎么使用的。。

read.c文件#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
int main(){int fd;char buf[128] = {0};int cnt = 0;//int mkfifo(const char *pathname, mode_t mode);if((mkfifo("./file",0600) == -1) && (errno == EEXIST)){printf("create fifo failed!\n");perror("because");}
//      int open(const char *pathname, int flags);fd = open("./file",O_RDONLY);if(fd < 0){printf("open fifo failed!\n");exit(-1);}else{printf("open successful!\n");}
//      ssize_t read(int fd, void *buf, size_t count);while(1){ int nread = read(fd,buf,50);printf("read %d byte,context: %s\n",nread,buf);cnt++;if(cnt == 5){break;}}close(fd);return 0;
}
write.c文件#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
int main(){int fd;char *str = "message write by son;read for father";int cnt;
//      int open(const char *pathname, int flags);fd = open("./file",O_WRONLY);if(fd < 0){printf("open fifo failed!\n");exit(-1);}else{printf("open successful!\n");}while(1){sleep(2);   int nwrite = write(fd,str,strlen(str));if(nwrite < 0){printf("write failed!\n");exit(-1);}cnt++;if(cnt == 5){break;}  }close(fd);return 0;
}

这里我们模拟通信,在read.c文件创建管道只读打开,在write.c文件中只写打开,当我们输入执行read的时候,会阻塞,在另一命令框中输入write执行才会输出数据流read

注意:read文件中EEXIST实际上是mkfifo的error值,当error等于EEXIST表明这个file文件流已经存在了,这点也可以在perror中查看

结果如下:
为了不刷屏,设置了sleep和次数。


!!!这里记录下小失误

read中buf没有分配空间,不能使用strlen,可以使用sizeof或者直接数字大小
read(fd,buf,50);

学习笔记——进程间通信之管道详解相关推荐

  1. java 检查bytebuf长度_Java学习笔记16-Netty缓冲区ByteBuf详解

    Java学习笔记16-Netty缓冲区ByteBuf详解 Netty自己的ByteBuf ByteBuf是为解决ByteBuffer的问题和满足网络应用程序开发人员的日常需求而设计的. JDK Byt ...

  2. spring学习笔记03-spring-DI-依赖注入详解(通过xml配置文件来配置依赖注入)

    spring学习笔记03-spring-DI-依赖注入详解 1.概念 2.构造函数注入 3.set方法注入 4.集合的注入 需要被注入的实体对象 package com.itheima.service ...

  3. 【学习笔记】线段树详解(全)

    [学习笔记]线段树详解(全) 和三个同学一起搞了接近两个月的线段树,头都要炸了T_T,趁心态尚未凉之前赶快把东西记下来... [目录] [基础]作者:\((Silent\)_\(EAG)\) [懒标记 ...

  4. [原创]Saltstack学习笔记:命令参数详解以及配置文件说明

    很久没有更新saltstack的文章了,今天还是来更新一点,又开始对saltstack复习了一下. 前边写了一点<saltstack入门概述(1)>以及<Saltstack如何安装( ...

  5. Laravel学习笔记汇总——Collection方法详解

    ## Laravel学习笔记汇总--Collection方法详解 本文参考:https:// laravel.com/docs/8.x/collections // 返回整个底层的数组 collect ...

  6. Android学习笔记——Android 签名机制详解

    Android 签名机制详解 近期由于工作需要在学习 Android 的签名机制,因为没有现成资料,只能通过开发者文档和阅读博客的方式对 Android 签名机制进行大致了解.过程中查阅到的资料相对零 ...

  7. [学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

    文章目录 引入概念 全套模板 变量声明 update ==rotate旋转== splay操作 insert插入 delete删除 查找x的位置 查找第k大 前驱/后继 极小值-inf和极大值inf的 ...

  8. cdt规约报文用程序解析_程序员必备的学习笔记《TCP/IP详解(二)》

    把这三个协议放到一起学习是因为这三个协议处于同一层,ARP 协议用来找到目标主机的 Ethernet 网卡 Mac 地址,IP 则承载要发 送的消息.数据链路层可以从 ARP 得到数据的传送信息,而从 ...

  9. [读书笔记]C#学习笔记三: C#类型详解..

    前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...

最新文章

  1. WxCountUp - 数字滚动(微信小程序插件)
  2. 人工智能python框架_Python 与 AI 智能框架 - 随笔分类 - Hopesun - 博客园
  3. python3改变路径出现的SyntaxError问题
  4. java判断时间为上午,中午,下午,晚上,凌晨
  5. 统计输入的字符串中各种字符的个数
  6. VS高版本编写C程序的C4996错误
  7. 使用js实现鼠标放置时显示下拉列表
  8. Funcode-贪吃蛇
  9. 商汤连发11款新品,把自己逼上“AI落地”极限
  10. 斐讯盒子t1 刷Android,斐讯盒子T1/N1刷机流水账
  11. Android 原生插件开发步骤
  12. 小米9android q测试版,MIUI Android Q Beta优先体验版已推送:小米9可尝鲜
  13. 是指因计算机网络不安全导致的风险,网络安全知识竞赛题库
  14. 15块rmb做一个语音识别控制的0.3W白光LED便利USB灯
  15. 鼠标双击DataGridView单元格变成ComboBox
  16. 【网络安全】入侵防御系统
  17. android edittext numberdecimal,android – 如何在“手机”软键盘上使用InputType = numberDecimal?...
  18. ACM教程 - 卡特兰数(Catalan)算法
  19. java怎样实现窗口可视化_java界面——可视化窗口入门级
  20. R代码学习(5)——数据类型(字符串)

热门文章

  1. Java+Netty+WebRTC、语音、视频、屏幕共享【聊天室设计实践】
  2. 主攻文推荐攻守都有系统_第五十五章 攻守转换
  3. 智衡跨境电商:跨境电商运营和国内电商运营差别在哪?
  4. gateway配置跨域
  5. python九宫格拼图,Python生成九宫格图片
  6. 淘宝订单接口|订单插旗备注,淘宝开放平台最稳定的店铺订单接口
  7. 临床试验中lm是什么职位_除了CRX职位,临床试验中还有这些岗位
  8. 深度:进入洗牌期的老年鞋市场对中国老年消费品行业的发展启示—足力健地位能否持续,奥康/红蜻蜓能否逆袭?
  9. 视频去水印、文案提取和智能配音,视频搬运合成速成教程,超简单
  10. springBoot+itext处理富文本转pdf