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


相关文章
|
10天前
麒麟系统mate-indicators进程占用内存过高问题解决
【10月更文挑战第7天】麒麟系统mate-indicators进程占用内存过高问题解决
65 2
|
10天前
|
存储 缓存 监控
Linux中内存和性能问题
【10月更文挑战第5天】
25 4
|
9天前
|
算法 Linux
Linux中内存问题
【10月更文挑战第6天】
11 2
|
10天前
|
存储 缓存 固态存储
|
13天前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
16 0
Linux c/c++之IPC进程间通信
|
13天前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
15 0
Linux c/c++进程间通信(1)
|
16天前
|
缓存 算法 调度
深入浅出操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅。我们将从进程管理的基本概念出发,逐步深入到内存管理的复杂世界,最终探索如何通过实践技巧来优化系统性能。文章将结合理论与实践,通过代码示例,帮助读者更好地理解操作系统的核心机制及其在日常技术工作中的重要性。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往操作系统深层次理解的大门。
|
13天前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
30 0
|
1月前
|
监控 Ubuntu API
Python脚本监控Ubuntu系统进程内存的实现方式
通过这种方法,我们可以很容易地监控Ubuntu系统中进程的内存使用情况,对于性能分析和资源管理具有很大的帮助。这只是 `psutil`库功能的冰山一角,`psutil`还能够提供更多关于系统和进程的详细信息,强烈推荐进一步探索这个强大的库。
38 1
|
2月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
260 0