进程间通信(System V 标准下的多种通信方式)

上一篇文章讲了进程间通信的一个方式之一:管道,也提到管道存在的字节流问题。这篇文章将讲到基于System V 标准的多种通信方式,包括:共享内存,信号量,消息队列。

共享内存

共享内存是最快的 IPC 形式 ,它的本质是在内存空间中的共享区开辟一块空间供用户直接使用,这样在对数据写入与读取时可以绕开内核的系统调用,达到极致的速度。(但是当多个进程同时读取同一块空间时会出现竞态条件,此时要搭配信号量、互斥锁等做同步,这部分还是需要内核支持的)。

来认识一下共享内存相关的几个函数:

用于创建共享内存的:

用于将共享内存段连接道进程地址空间的:

用于将共享内存段与当前进程脱离的:

用于控制共享内存的:

对于每个函数的参数含义就不做说明了,可以使用 man 命令自行查看。

共享内存不会有管道那样的读取数据问题,因为共享内存是大小固定的区域,你往这个区域里面写什么,读取时读到的就是什么。

共享内存不会自带同步机制,就是前面说的多个进程同时访问时,这个时候我们需要将共享内存保护起来,不然会出现数据错乱。保护方法有信号量、互斥锁,互斥锁我们没有学过,但信号量是接下来的话题,不妨先学习了信号量再考虑它是如何实现保护共享内存的功能的。

信号量

信号量本质是一个计数器,这里又涉及到了引用计数的概念,用来表示临界资源中资源的数量多少。在进程要访问资源之前,需要先申请信号量,也就是对一块资源的 "预定"。

我们把共享内存空间想象成一个电影院,申请信号量的行为就是买票。你坐在电影院的哪一个座位,你的票是决定因素,如果没有票,就可能出现座位使用权的争执。

那么,信号量如何解决共享内存的问题呢?首先我们得知道,信号量本身就是一个共享的资源,可以理解为每个人都可以看到电影院的座位预定情况。对于一块共享内存,如果已经有进程在访问,那么其他进程便不能访问,当那个进程访问完共享内存并主动释放信号量,下一个进程才能访问。

申请信号量,P操作,释放信号量,V操作。

消息队列

消息队列就是将要共享的资源维护成一个队列。

消息队列的形式:A写入一个信息,内核存起来,B随时来取用,写端完全不影响读端。有点像弄了很多个大小不一的共享内存,然后串联起来。

它每一块数据都有边界,所以不会出现管道那样的问题。它自带同步机制,不会因为多个进程同时访问导致数据错乱。

System V

以上三种通信方式都是 System V 标准下的,那么什么是System V标准呢?为什么要用System V标准呢?

首先,System V标准其实就是一种 进程间通信的思路,它的特点是:内核对象全局可见,像上面的共享内存,信号量和消息队列,其实它们的创建都需要一个 Key,只要知道同一个 Key ,任何进程都能打开这些共享的资源。

正是这种特性,让 System V 下的 IPC 都可以被当作同一种资源来管理。

在内核中有一个 ipc_id_ary 结构体,里面有一个柔性数组( p0 ),用来存放这些资源,它们本质相同,所以可以存放在同一个数组中,所有 IPC 对象都共享一个通用头部struct kern_ipc_perm),包含 key、id、权限等信息。

内核通过 ipc_id_ary 统一管理,而具体的类型(共享内存 / 信号量 / 消息队列)通过后续的强转来区分,不属于该类型的强转则得不到正确的信息,这就是使用System V标准的意义,也是用C语言实现出多态的高级教科书!

相关推荐
梦想的颜色7 小时前
【Docker原理】Docker 容器一文打尽:生命周期、环境管控、迁移备份、日志进程排查、垃圾清理
运维·docker·容器·容器生命周期·容器日志排查·容器迁移备份·容器进程管理
欢呼的太阳9 小时前
数据库设计Step by Step (10)——范式化
服务器·数据库·oracle
夜雪一千9 小时前
Python enumerate() 函数完整详解:遍历同时获取索引,告别手动计数
服务器·windows·python
donoot10 小时前
Linux系统下图书馆级电子书全自动标准化分类整理完整实施方案
大数据·linux·运维·电子书管理
ITKEY_10 小时前
macOS brew 安装的nginx 文件在哪里?
运维·nginx·macos
Felix-lxd11 小时前
Ubuntu 22.04 配置 Nginx
linux·nginx·ubuntu
Elastic 中国社区官方博客11 小时前
如何比较两个 Elasticsearch 索引并找出缺失的文档
大数据·运维·数据库·elasticsearch·搜索引擎
大E帝国子民111 小时前
MacOS 安装Seismic Unix
服务器·macos·unix
Tim_Van12 小时前
在 CentOS 7 中安装 Chromium 的完整步骤
linux·运维·chrome·centos
德福危险12 小时前
富有想象力的XSS盲打:靶机练习之Tempus_fugit5
服务器·网络·xss