Linux之进程间通信——system V(共享内存、消息队列、信号量等)(上)

简介: Linux之进程间通信——system V(共享内存、消息队列、信号量等)(上)

前言

本文介绍了另一种进程间通信——system V,主要介绍了共享内存,消息队列、信号量,当然消息队列了信号量并非重点,简单了解即可。


一、共享内存

1.共享内存的基本原理

共享内存:不同的进程为了进行通信看到的同一个内存块,该内存块被称为共享内存。

进程具有独立性,它的内核数据结构包括对应的代码,数据与页表都是独立的。

OS系统为了让进程间可以实现通信:1.在物理内存上申请一块内存空间 2.将申请好的内存分别与各个进程的页表之间建立映射,然后在各个进程的虚拟地址空间中将虚拟地址与页表建立映射,从而建立起物理地址与虚拟地址的联系。

如果不想继续通信,就取消进程与内存间的映射关系,释放内存。

  1. 我们将创建好的内存称为共享内存
  2. 将进程与共享内存建立映射的操作称为挂接
  3. 把取消进程与内存的映射关系这一操作称为关联
  4. 把释放内存称为释放共享内存

共享内存的建立:在物理内存当中申请共享内存空间;将申请到的共享内存嘎姐到地址空间(建立映射关系)。

共享内存的释放:共享内存与地址空间去关联(取消映射关系),释放共享内存空间(将物理内存归还系统)。

对于共享内存的理解

对比C语言中的malloc可以在物理内存中申请空间,并将开辟好的空间通过页表映射到进程地址空间当中。system V进程间通信,是专门设计的,用于IPC;共享内存是一种通信方式,所有想进行通信的进程都可以使用(OS一定可能会同时存在很多的共享内存)

2.共享内存的创建

  1. shmget:用来创建共享内存
  2. 参数认识:

shmflg:通常有两个选项:IPC_CREATIPC_EXCL

  • IPC_CREAT:共享内存不存在,则创建,如果存在,则获取
  • IPC_EXCL:无法单独使用,只能配合IPC_CREAT使用。IPC_CREAT | IPC_EXCL如果不存在就创建,如果存在就报错

size:共享内存的大小

key:共享内存的唯一性标识,保证进程看到同一份共享内存。如何形成key?用ftok

ftok:形成key

ftok是通过存在的路径名pathname以及设置的标识符proj_id来形成一个key值,通过shmget创建共享内存时,key值会被填充到维护共享内存的数据结构当中。

key_t getkey()
  {
          key_t = ftok(PATHNAME, PROJ_JD);
          if(k < 0)
          {
                  cout<<"error:"<<errno<<":"<<strerror(errno)<<endl;
                  exit(1);
          }
          return k;
  }

为什么要存在key?

OS中一定存在很多的共享内存,而共享内存本质就是在内存中申请一块空间,这个key就是用来唯一标识共享内存的。

OS申请的共享内存,那么它一定会对共享内存进行管理(先描述,再组织),共享内存 = 物理内存块 + 共享内存的相关属性。

如果两个进程为了进行通信使用共享内存,那么一定要让两干进程看到同一个key的共享内存,那么key值存在哪里呢?key作为共享内存的唯一标识,应该存在共享内存的相关属性集合。描述共享内存的数据结构的字段struct shm中存着key。

共享内存数据结构的第一个成员是shm_permshm_perm是一个ipc_perm类型的结构体变量,每个共享内存的key值都存储在shm_perm中。

// ipc_perm结构体如下
struct ipc_perm{
  key_t __key;
  uid_t uid;
  gid_t gid;
  uid_t cuid;
  gid_t cgid;
  unsigned short mode;
  unsigned short __seq;
};

3.共享内存的控制

shmctl:控制共享内存

参数

shmid控制共享内存的标识符;

cmd控制种类;

buf控制共享内存的数据结构(一般设置为NULL)。

返回值

返回0表示成功,返回-1表示失败。

共享内存的内核数据结构

struct shmid_ds{
  struct ipc_perm shm_perm;
  size_t shm_segsz;
  time_t shm_atime;
  time_t shm_dtime;
  time_t shm_ctime;
  pid_t shm_cpod;
  pid_t shm_lpod;
  shmatt_t shm_nattch;
  //…

4.共享内存的关联

shmat:关联共享内存

参数

shmaddr:指定虚拟地址(一般设置为nullptr);

shmflg:读取权限(一般设置为0)。

5.共享内存的去关联

shmdt:去关联

6.查看IPC资源

对于管道,进程退出,文件描述符会自动被释放(文件描述符的生命周期是随进程的),但是对于共享内存来说不是这样的,共享内存的生命周期是随OS的,而不是随进程,这是所有system V进程间的共性。

7.查看共享内存

ipcs -m

8.删除共享内存

ipcsrm -m (shmid)二、实现进程间通信(代码)

文件comm.hpp


相关文章
|
1月前
|
消息中间件 存储 Linux
|
2月前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
44 0
Linux c/c++之IPC进程间通信
|
2月前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
38 0
Linux c/c++进程间通信(1)
|
4月前
|
消息中间件 Linux
Linux进程间通信
Linux进程间通信
47 1
|
4月前
|
开发者 API Windows
从怀旧到革新:看WinForms如何在保持向后兼容性的前提下,借助.NET新平台的力量实现自我进化与应用现代化,让经典桌面应用焕发第二春——我们的WinForms应用转型之路深度剖析
【8月更文挑战第31天】在Windows桌面应用开发中,Windows Forms(WinForms)依然是许多开发者的首选。尽管.NET Framework已演进至.NET 5 及更高版本,WinForms 仍作为核心组件保留,支持现有代码库的同时引入新特性。开发者可将项目迁移至.NET Core,享受性能提升和跨平台能力。迁移时需注意API变更,确保应用平稳过渡。通过自定义样式或第三方控件库,还可增强视觉效果。结合.NET新功能,WinForms 应用不仅能延续既有投资,还能焕发新生。 示例代码展示了如何在.NET Core中创建包含按钮和标签的基本窗口,实现简单的用户交互。
81 0
|
5月前
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
5月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
1月前
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
3月前
|
消息中间件
手撸MQ消息队列——循环数组
队列是一种常用的数据结构,类似于栈,但采用先进先出(FIFO)的原则。生活中常见的排队场景就是队列的应用实例。在数据结构中,队列通常用数组实现,包括入队(队尾插入元素)和出队(队头移除元素)两种基本操作。本文介绍了如何用数组实现队列,包括定义数组长度、维护队头和队尾下标(front 和 tail),并通过取模运算解决下标越界问题。此外,还讨论了队列的空与满状态判断,以及并发和等待机制的实现。通过示例代码展示了队列的基本操作及优化方法,确保多线程环境下的正确性和高效性。
56 0
手撸MQ消息队列——循环数组
|
4月前
|
消息中间件 存储 缓存
一个用过消息队列的人,竟不知为何要用 MQ?
一个用过消息队列的人,竟不知为何要用 MQ?
193 1