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

【Linux】进程间通信 续

目录

管道的原理(匿名管道)

核心原理

站在内核的角度看管道的本质

接口

创建管道文件

代码示例

管道的特征

管道读写端的四种情况

管道的应用场景

命令行的管道。

使用管道实现进程池

初始化

控制子进程

退出

命名管道

命名管道的理解

代码示例

服务端

客户端

日志

共享内存(system v)

原理解析

代码案例

让两个进程看到同一份资源

开始通信

共享内存的特性

共享内存的属性

利用管道实现同步机制

消息队列(system v)

原理

接口

信号量(system v)

理解信号量

接口

IPC在内核中的数据结构设计


管道的原理(匿名管道)

文件描述符表,文件的加载,内存中生成一个文件对象,每个文件对象有inode,方法集,文件缓冲区,磁盘中的文件属性加载到inode,文件内容加载到文件缓冲区。

内存级文件,不在磁盘中,只在内存中运转,类似于临时文件。

子进程会拷贝父进程PCB,文件描述符表,但不会拷贝文件对象。所以它们指向同一个文件对象。

父子进程可以同时看到这个文件,意味着可以在这个内存级文件的缓冲区进行通信了。

管道就是文件,只不过是内存级文件。


核心原理

父进程以读和写打开管道文件。

父子进程都指向管道文件。

各自关闭一端读或写,可实现单向通信。


站在内核的角度看管道的本质

父进程同时用读方式和写方式打开管道文件,会创建读文件对象和写文件对象,但它们是同一个文件,都是同一个inode,同一个方法集,同一个缓冲区。

把父进程写关闭,子进程读关闭。

上述讲的是匿名管道。


接口

创建管道文件

成功返回0,失败返回-1并设置错误码。

参数是输出型参数。

代码示例

创建子进程各自关闭一端。子进程写父进程读。

子进程构建内容,写给管道文件。

父进程从管道文件接收信息。


管道的特征


管道读写端的四种情况

读端如果关闭,写端就会被13信号杀死。


管道的应用场景

命令行的管道。


使用管道实现进程池

模型思路:父进程写子进程读。

Makefile

描述需要管理的信息

组织信息并初始化

控制子进程

控制退出

初始化

创建多个管道和多个子进程,并记录想要的信息。

子进程的任务

接收父进程给的任务码,执行对应任务

控制子进程

给子进程发送任务码

退出

关闭写端

等待子进程退出


命名管道

指令

创建命名管道


命名管道的理解

不同的进程会以读写方式打开不同的文件对象,但都指向同一个文件的inode,方法集,缓冲区。

这样可以让不同的进程看到同一份资源

不同进程通信时不想要刷盘就诞生了管道文件,也就是内存级文件,管道文件不需要刷盘。

不同进程通信的前提是看到同一份资源,为了保证同一份资源我们就用了路径+文件名确定,因为具有唯一性,所以叫命名管道。


代码示例

makefile

生成两个可执行程序,一个服务端,一个客户端。

服务端

创建管道文件

第一个参数是路径文件名,第二个参数是文件权限

删除管道文件

参数是路径文件名

把创建和删除放到类的构造和析构中,用类的生命周期来管理。

打开管道文件

开始通信


 

客户端

打开文件

开始通信,用户输入

cin 是空格和回车分割,getline是回车分割。

关闭


日志

形参实例化从右向左

va_list 是一个char*

va_start让这个指针指向第一个参数的下一位

va_arg 根据类型提参数

va_end 指针置空

时间

输入时间戳可以转化为一个时间结构体

日志格式分为两部分

左部分是日志等级和时间

右部分是用户自定义部分

打印日志有三种,往屏幕打印,往文件打印,往不同文件打印


共享内存(system v)

原理解析

在物理内存创建一块区域,这块区域都映射在不同进程的共享区,进程对共享区的操作实现对同一块区域的交流。

释放共享内存


代码案例

让两个进程看到同一份资源

在系统里创建一个共享内存

唯一标识符key

获取共享内存

1. 获取key

2. 创建共享内存

key与shmid

查看共享内存 ipcs -m 

手动关闭是 ipcrm -m shmid

共享内存的权限设置

创建共享内存与获取共享内存

共享内存的大小

挂接

去关联

传入挂接得到的地址

释放共享内存

a进程负责创建和删除共享内存,b进程负责获取共享内存。


开始通信

a进程读,b进程写

a进程直接从共享内存获取信息

b进程直接写到共享内存


共享内存的特性


共享内存的属性

获取共享内存属性

利用管道实现同步机制

获取key

获取共享内存分为创建和单纯获取

进程a,收到提醒后才去访问共享内存。

进程b,写完信息后通知对方访问。


消息队列(system v)

原理

不同的进程看到同一个队列,将带类型的数据块发送给队列,从队列上获取自己想要的数据。


接口

指令查看和删除消息队列


信号量(system v)

共享内存没有保护机制

临界资源,临界区


理解信号量

信号量的本质是计数器。

临界资源被分成很多块资源,信号量记录着还剩多少块资源。

每当执行流申请资源,信号量就记录资源被使用一份,资源使用完了就不给申请了,除非执行流还回来。

使用资源之前得先申请

原子的PV操作

概念总结

接口

申请信号量

第二个参数是申请信号量的个数,一般为1。

操作信号量

设置信号量

sembuf结构体需要自己定义

sem_op控制PV操作


 

IPC在内核中的数据结构设计

系统用数组管理IPC资源,数组存放的是第一个字段,可以直接访问ipc_perm结构体,如果想访问整个ipc的结构体只需要强转类型即可,这是多态最早的样子。


http://www.kler.cn/a/572905.html

相关文章:

  • 美颜SDK架构揭秘:人脸美型API的底层实现与优化策略
  • 立体仓WMS同MES制造的协同
  • upload-labs Pass5-18 文件上传
  • 观察者模式的C++实现示例
  • 从零开始的kafka学习 (一)| 概念,Java API
  • 从vue源码解析Vue.set()和this.$set()
  • 深入浅出:UniApp 从入门到精通全指南
  • 360图片搜索爬虫|批量爬取搜索图片
  • 关于在vue3中的动态组件component标签上给ref属性动态赋值的问题
  • Java进阶-SpringCloud设计模式-工厂模式的设计与详解
  • 原型链与继承
  • 【RAG 篇】万字长文:向量数据库选型指南 —— Milvus 与 FAISS/Pinecone/Weaviate 等工具深度对比
  • 软考架构师笔记-进程管理
  • 自动驾驶---不依赖地图的大模型轨迹预测
  • AI与.NET技术实操系列
  • Python:函数的各类参数以及函数嵌套
  • Mono里运行C#脚本44—System.Console.WriteLine()函数的生成过程
  • L2-001 紧急救援
  • CS144 Lab Checkpoint 0: networking warm up
  • java数据结构_Map和Set_HashMap 底层源码解读_9.5