当前位置: 首页 > news >正文

进程间通信IPC

前言

        进程是操作系统中独立运行的程序单元,每个进程拥有自己的内存空间。由于进程之间的内存空间是隔离的,不能直接访问彼此的内存,因此需要借助IPC来实现进程间的数据交换

一.管道

进程间通信的本质是让不同的进程看到同一份资源,  我们先来看管道是如何做到的

管道特性

    1. 自带同步机制
    2. 多用于血缘关系进程进行通信,常见与父子
    3. pipe是面向字节流的
    4. 父子退出,管道自动释放,文件的生命周期是随进程的
    5. 管道只能单向通信

管道的四种情况

  1. 管道内部没有数据且子进程不关闭自己的写端文件,  读端就要阻塞等待,直到pipe有数据
  2. 管道内部被写满且读端不关闭自己的fd,  写端写满之后,写端就要阻塞等待
  3. 对于写端而言:关闭了pipe,  读端会将pipe中的数据读完,最后就会读到返回值为0,表示读结束,类似读到了文件的结尾
  4. 读端关闭,写端再写,OS会直接终止写入的进程(子进程),通过信号SIGPIPE(13)信号杀掉进程

匿名管道

原理

        父进程创建的子进程会继承父进程打开的文件描述符,  让父子进程看到同一个管道文件

然后只需关闭不需要的读写端即可

使用

        这个系统调用能让系统维护一个匿名管道,  匿名管道是由操作系统维护的一段缓冲区,  并不会创建文件

        pipefd为输出型参数,其本质是一个长度为2的数组,   pipifd[0]表示读端文件描述符, pipefd[1]表示写端文件描述符

        返回 0 表示开辟管道成功,  返回 -1 表示开辟管道失败,并且会设置错误码

比如父进程写入管道,  子进程读取管道数据

int main()
{int fd[2];pipe(fd);//创建匿名管道int rfd = fd[0];int wfd = fd[1];pid_t id = fork();//创建子进程if(id == 0){close(wfd);//子进程关闭写文件描述符//这里就可以执行一些读取管道的方法exit(0);}close(rfd);//父进程关闭读文件描述符//这里执行一些写入管道的方法waitpid(id, NULL, 0);return 0;
}

命名管道

原理

让两个独立的进程打开同一个管道文件

使用

使用mkfifo创建一个命名管道文件

然后就可以让不同的进程打开读写端来完成进程间通信

二.System V

1.共享内存

原理

将一片内存通过页表映射到不同的进程的进程地址空间上

使用

使用ftok获取唯一性标识,  再使用shmget获取共享内存的id

size:  共享内存的大小,  共享内存在内核中以4KB为基本单位

flg常用选项:

  • IPC_CREAT:如果共享内存不存在,就创建之,如果共享内存已经存在,直接获取它
  • Ipc_EXCL:不能单独使用,没意义
  • IPC_CREATIPC_EXCL:如果共享内存不存在,就创建之,如果共享内存已经存在,出错返回

控制共享内存

cmd常用选择

  • IPC_STAT 获取共享内存的属性
  • IPC_RMID 删除指定共享内存

挂接和去关联共享内存

这一步实际就是将共享内存映射到进程的地址空间上

shmat 挂接指定共享内存, 返回一个指针指向共享内存的起始位置

shmid :  共享内存id

shmaddr :  可选指定位置挂接

shmflg常用选项

  • 0: 可读可写
  • SHM_RDONLY:  只读

shmdt  去关联,  传入已挂接的共享内存起始地址

2.消息队列

原理

一个进程向队列放数据块,  另一个进程拿取

使用

创建一个消息队列

msgflg常用选项

  • IPC_CREAT: 如果指定的key不存在,则创建一个新的消息队列,如果已经存在,则直接获得原先的消息队列
  • IPC_EXCL: 如果指定的key已经存在,则创建失败

控制消息队列

cmd常用选项

  • IPC_STAT:获取消息队列的状态信息
  • IPC_SET:设置消息队列的某些属性
  • IPC_RMID:删除消息队列

写入操作

msqid:消息队列的标识符
msgp:指向要写入的消息内容的指针
msgsz:要写入内容的字节数
msgflg常用选项

  • 0: 默认
  • IPC_NOWAIT: 如果消息队列已满,则立即返回

读取操作

msqid:消息队列的标识符

msgp:读到哪个缓冲区

msgsz:缓冲区大小

msgtyp: 指定要接收的消息类型

mesflg常用选项

  • 0: 默认
  • IPC_NOWAIT: 如果消息队列已满,则立即返回

3.信号量

原理

信号量是一种资源预定机制,  本质是个计数器

        进程访问资源前,要先申请一个信号量,用于预定资源,一旦预定成功,不管这个进程使不使用这个资源,  这个资源都不会再被分配给其他进程,  进程只有成功申请到了信号量才能访问这个资源

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • GIT指令大全详解
  • Android 获取短信验证
  • 制造企业技术图纸不受控的影响与规避方法
  • 漏洞复现-Apache Commons Text远程代码执行漏洞(CVE-2022-42889)
  • 使用 OpenAI Whisper v2 模型进行中英文混合语音识别
  • SpringBoot + Hadoop + HDFS + Vue 实现一个简单的文件管理系统
  • linux常用命令备忘录
  • Mapper使用记录
  • Java 并发编程:线程变量 ThreadLocal
  • OceanBase VS Doris 对比分析
  • Bio_ClinicalBERT 医疗临床领域大模型,参数里 0.11B【Hugging face 】
  • C语言 软件设计的七大原则,及其应用案例
  • labelme标注的图像分割json文件转图片格式
  • Flutter 学习 一部分注意点记录
  • css实现磨砂效果(filter 与 backdrop-filter 的对比分析)
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Golang-长连接-状态推送
  • IDEA常用插件整理
  • Js实现点击查看全文(类似今日头条、知乎日报效果)
  • Nacos系列:Nacos的Java SDK使用
  • Redash本地开发环境搭建
  • Redux系列x:源码分析
  • SSH 免密登录
  • Three.js 再探 - 写一个跳一跳极简版游戏
  • 创建一种深思熟虑的文化
  • 搭建gitbook 和 访问权限认证
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 漂亮刷新控件-iOS
  • 前端路由实现-history
  • 深入浅出Node.js
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 关于Android全面屏虚拟导航栏的适配总结
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗? ...
  • ​LeetCode解法汇总2304. 网格中的最小路径代价
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​什么是bug?bug的源头在哪里?
  • #Lua:Lua调用C++生成的DLL库
  • (02)Unity使用在线AI大模型(调用Python)
  • (Java企业 / 公司项目)点赞业务系统设计-批量查询点赞状态(二)
  • (Pytorch框架)神经网络输出维度调试,做出我们自己的网络来!!(详细教程~)
  • (搬运以学习)flask 上下文的实现
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (四)搭建容器云管理平台笔记—安装ETCD(不使用证书)
  • (四)模仿学习-完成后台管理页面查询
  • (循环依赖问题)学习spring的第九天
  • (转)memcache、redis缓存
  • *上位机的定义
  • .ai域名是什么后缀?
  • .apk 成为历史!
  • .bat批处理(七):PC端从手机内复制文件到本地
  • .Net Core和.Net Standard直观理解
  • .NET Framework .NET Core与 .NET 的区别
  • .net MySql