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

【Linux】进程间通信

目录

  • 1. 通信
  • 2. 匿名管道
    • 2.1 匿名管道的原理
    • 2.2 匿名管道的有关代码编写
      • 2.2.1 匿名管道代码编写
      • 2.2.2 进程池代码
  • 3. 命名管道
    • 3.1 创建命名管道的函数
    • 3.2 命名管道的原理
    • 3.3 命名管道代码的编写
  • 4. system V共享内存
    • 4.1 system V共享内存的原理
    • 4.2 相关函数
      • 4.2.1 shmget 函数
      • 4.2.2 ftok函数
      • 4.2.3 查看和删除共享内存
      • 4.2.4 shmat 函数
      • 4.2.5 shmctl 函数
    • 4.3 共享内存的性质
    • 4.4 共享内存代码编写

1. 通信

  • 通信概念:两个或者多个进程实现数据层面的交互
    因为进程独立性的存在,导致进程通信的成本比较高

  • 进程间通信的本质:必须让不同的进程看到同一份”资源”------特定形式的内存空间。

  • 这个”资源”谁提供?一般是操作系统
    为什么不是我们两个进程中的一个呢?假设一个进程提供,这个资源属于谁?这个进程独有,破坏进程独立性。

  • “资源”从创建,使用,释放,都是使用系统调用接口!

  • 基于文件级别的通信方式--------管道

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

2. 匿名管道

2.1 匿名管道的原理

管道就是文件
在这里插入图片描述

现在还要一个问题。
如果父进程只是以写或读的形式打开文件,那么子进程也只能是以写或读的形式打开文件,所以父子只能同时读或写。但是我们需要父写子读 或 父读子写。那么只能如下操作:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
真正的管道通信原理:
也说明了管道只能进行单向通信。
在这里插入图片描述

  • 如果我要进行双向通信呢?使用多个管道
  • 如果没有任何关系,可以用我们刚刚讲的原理进行通信呢?不能
    必须是父子关系,兄弟关系,爷孙关系…--------血缘关系,常用于父子
  • 因为管道的内存级文件是匿名的,所以叫做匿名管道‘

2.2 匿名管道的有关代码编写

2.2.1 匿名管道代码编写

在这里插入图片描述
管道的特征:

  • 具有血缘关系的进程进行进程间通信
  • 管道只能单向通信
  • 父子进程是会进程协同的,同步与互斥的——保护管道文件的数据安全
  • 管道是面向字节流的
  • 管道是基于文件的,而文件的生命周期是随进程的!

代码gitee链接: 管道代码编写gitee链接

管道的4种情况:
1.读写端正常,管道如果为空,读端就要阻塞
2.读写端正常,管道如果被写满,写端就要阻塞
3.读嘴正常读,写端关闭,读一段时间后,读端就会读到0,表明读到了文件(pipe)结尾,不会被阻塞
4. 写端是正常写入,读端关闭了。操作系统就要杀掉正在写入的进程。如何干掉?通过信号杀掉。杀掉因为操作系统是不会做,低效,浪费等类似的工作的。
通过13号信号-----SIGPIPE杀掉进程

2.2.2 进程池代码

gitee代码:代码

3. 命名管道

3.1 创建命名管道的函数

创建命名管道的函数:
在这里插入图片描述
在这里插入图片描述
使用该函数之后,一个新的文件就会被创建,该文件为内存级文件。
文件名和路径由自己确定。

3.2 命名管道的原理

具有血缘关系的进程使用匿名管道,没有血缘关系的进程则使用命名管道。
如果两个不同的进程打开同一个文件的时候,在内核中,操作系统只会打开一个文件。
因为该管道文件不需要刷盘,所以直接创建内存级文件。
如何打开同一个文件,文件的文件名+路径相同即可。
在这里插入图片描述

3.3 命名管道代码的编写

gitee链接:代码
内含日志代码编写

4. system V共享内存

4.1 system V共享内存的原理

再次强调:进程间通信的原理是让进程看到同一份资源
在这里插入图片描述

如果要申请共享内存、释放共享内存、关联、去关联-----这些操作都是进程直接做的吗?不是。直接由操作系统来做。
需求方—> 系统调用 —> 执行方

4.2 相关函数

4.2.1 shmget 函数

作用:为共享内存申请空间
在这里插入图片描述

4.2.2 ftok函数

作用:用pathname和proj_id确定一个key
在这里插入图片描述

  1. key是一个数字,这个数字是几,不重要。关键在于它必须在内核中具有唯一性,能够让不同的进程进行唯一性标识
  2. 第一个进程可以通过key创建共享内存,第二个之后的进程,只要拿着同一个key就可以和第一个进程看到同一个共享内存了!
  3. 对于一个已经创建好的共享内存,key在哪?key在共享内存的描述对象中!
  4. 该函数使key的矛盾冲突较小
  5. 当路径不存在时,key就会返回-1;当key与系统中的共享内存相同时,就需要更改pathname或proj_id;

4.2.3 查看和删除共享内存

共享内存的生命周期是随内核的!
用户不主动关闭,共享内存会一直存在。
除非内核重启(用户释放)
在这里插入图片描述

key:操作系统内标定唯一性
shmid:只在你的进程内,用来表示资源的唯一性!

4.2.4 shmat 函数

在这里插入图片描述

4.2.5 shmctl 函数

作用:删除共享内存
在这里插入图片描述

4.3 共享内存的性质

  1. 共享内存没有同步互斥之类的保护机制
  2. 共享内存是所有的进程间通信中,速度最快的!因为拷贝少,管道要拷贝2次,共享内存1次也不用
  3. 共享内存内部的数据,由用户自己维护!

4.4 共享内存代码编写

链接如下:
共享内存代码编写,其中利用了管道解决了共享内存同步问题。

相关文章:

  • 批量创建BOM的RFC接口
  • 常见的设计模式和应用场景(一)
  • 文本转语音-音画适时推送rtsp并播放
  • 静态路由实验
  • Spring Boot/Spring Cloud 整合 ELK(Elasticsearch、Logstash、Kibana)详细避坑指南
  • 【CSS3】元婴篇
  • [数据结构]并查集
  • 【 <一> 炼丹初探:JavaWeb 的起源与基础】之 JavaWeb 项目的部署:从开发环境到生产环境
  • 智能焊机监测系统:打造工业安全的数字化盾牌
  • Git合并工具在开发中的使用指南
  • 常用中文开源embedding模型应用
  • printk相关说明
  • 谷歌AI最新发布的可微分逻辑元胞自动机(DiffLogic CA)
  • ubuntu-学习笔记-nginx+php
  • MATLAB表格Table与时间序列Timetable的高效操作方法
  • MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议)
  • L1-088 静静的推荐
  • QT中委托QStyledItemDelegate的使用
  • 6-langchang多模态输入和自定义输出
  • Apache POI详解
  • 越老越妖的库里,成了火箭季后赛里一晃十年的噩梦
  • 巴菲特宣布将于年底退休,“接班人”什么来头?
  • 申活观察|人潮涌动成常态,豫园为何常来常新?
  • 德雷克海峡发生6.4级地震,震源深度10千米
  • 空间站第八批科学实验样品返抵地球并交付科学家
  • 解放日报:让算力像“水电煤”赋能千行百业