首页 > 系统相关 >共享内存的创建和映射过程

共享内存的创建和映射过程

时间:2023-11-26 22:32:26浏览次数:33  
标签:ns struct 映射 创建 ids file 共享内存 shm

消息队列、共享内存、信号量的机制:它们在使用之前都要生成 key,然后通过 key 得到唯一的 id,并且都是通过 xxxget 函数。在内核里面,这三种进程间通信机制是使用统一的机制管理起来的,都叫 ipcxxx。为了维护这三种进程间通信进制,在内核里面,我们声明了一个有三项的数组。

通过这段代码,来具体看一看。

struct ipc_namespace {
......
  struct ipc_ids  ids[3];
......
}

#define IPC_SEM_IDS  0
#define IPC_MSG_IDS  1
#define IPC_SHM_IDS  2

#define sem_ids(ns)  ((ns)->ids[IPC_SEM_IDS])
#define msg_ids(ns)  ((ns)->ids[IPC_MSG_IDS])
#define shm_ids(ns)  ((ns)->ids[IPC_SHM_IDS])

根据代码中的定义,第 0 项用于信号量,第 1 项用于消息队列,第 2 项用于共享内存,分别可以通过 sem_ids、msg_ids、shm_ids 来访问。

这段代码里面有 ns,全称叫 namespace。可能不容易理解,你现在可以将它认为是将一台 Linux 服务器逻辑的隔离为多台 Linux 服务器的机制,它背后的原理是一个相当大的话题,我们需要在容器那一章详细讲述。现在,你就可以简单的认为没有 namespace,整个 Linux 在一个 namespace 下面,那这些 ids 也是整个 Linux 只有一份。

共享内存的创建和映射过程。

  1. 调用 shmget 创建共享内存。
  2. 先通过 ipc_findkey 在基数树中查找 key 对应的共享内存对象 shmid_kernel 是否已经被创建过,如果已经被创建,就会被查询出来,例如 producer 创建过,在 consumer 中就会查询出来。
  3. 如果共享内存没有被创建过,则调用 shm_ops 的 newseg 方法,创建一个共享内存对象 shmid_kernel。例如,在 producer 中就会新建。
  4. 在 shmem 文件系统里面创建一个文件,共享内存对象 shmid_kernel 指向这个文件,这个文件用 struct file 表示,我们姑且称它为 file1。
  5. 调用 shmat,将共享内存映射到虚拟地址空间。
  6. shm_obtain_object_check 先从基数树里面找到 shmid_kernel 对象。
  7. 创建用于内存映射到文件的 file 和 shm_file_data,这里的 struct file 我们姑且称为 file2。
  8. 关联内存区域 vm_area_struct 和用于内存映射到文件的 file,也即 file2,调用 file2 的 mmap 函数。
  9. file2 的 mmap 函数 shm_mmap,会调用 file1 的 mmap 函数 shmem_mmap,设置 shm_file_data 和 vm_area_struct 的 vm_ops。
  10. 内存映射完毕之后,其实并没有真的分配物理内存,当访问内存的时候,会触发缺页异常 do_page_fault。
  11. vm_area_struct 的 vm_ops 的 shm_fault 会调用 shm_file_data 的 vm_ops 的 shmem_fault。
  12. 在 page cache 中找一个空闲页,或者创建一个空闲页。

共享内存的创建和映射过程_#define

共享内存的创建和映射过程_共享内存_02



标签:ns,struct,映射,创建,ids,file,共享内存,shm
From: https://blog.51cto.com/key3feng/8572929

相关文章

  • Centos6.10创建KVM虚拟环境
    实验环境:服务器操作系统Centos6.10,使用KVM虚拟机,在该服务器上配置三台操作系统为Centos7.9的虚拟机,网络连接方式采用NAT连接,(关于桥接和NAT连接的区别,可查看:CentOS6.9下KVM虚拟机网络Bridge(网桥)方式与NAT方式详解)查看cpu信息输入grep-E'(vmx|svm)'/proc/cpuinfo,如果输出......
  • 腾讯云创建镜像
    title:没有手都可以在腾讯云创建镜像banner_img:https://cloud.studyinglover.com/api/raw/?path=/photos/blog/33a1d238f41bcd6994390b5a52067cd6.pngdate:2023-6-1621:15:00categories:-踩坑腾讯云是国内顶级的云服务商。在大型项目上环境配置和编译是很多人的噩梦,当......
  • Vue项目的创建、运行与端口号修改
    前言:Vue-cli是Vue官方提供的一个脚手架,用于快速生成一个Vue的项目模板,依赖于NodeJS环境NodeJS下载:NodeJS安装下载Vue-cli下载:Vue-cli下载一.Vue图形化创建项目1.建立一个文件夹,保存Vue项目2.在该文件夹的目录上输入cmd打开命令行3.令行输入vueui打开Vue项目管理......
  • 第10次-创建一个在线网站
    这个作业属于哪个课程https://edu.cnblogs.com/campus/uzz/cs3这个作业要求在哪里https://edu.cnblogs.com/campus/uzz/cs3/homework/13118这个作业的目标第10次-创建一个在线网站创建一个在线网站我是使用阿里云服务器为平台做了一个在线网站网站的链接:http:......
  • 创建型设计模式05-抽象工厂模式
    1、抽象工厂模式介绍抽象工厂模式(AbstractFactoryPattern)是一种创建型设计模式,围绕一个超级工厂创建其他工厂,也称作为工厂的工厂(大工厂里的小工厂)。在抽象工厂模式中,接口负责创建一组相关对象的工厂,而不需要显式指定它们的类。这种设计模式能够将客户端与具体的实现分离,从而使得......
  • flask循环创建HTML标签
    app.pyfromflaskimportFlask,render_templateapp=Flask(__name__)@app.route('/')defindex():items=['item1','item2','item3']returnrender_template('index.html',items=items)......
  • 第10次-创建一个在线网站
    这个作业属于哪个课程https://edu.cnblogs.com/campus/uzz/cs3这个作业要求在哪里https://edu.cnblogs.com/campus/uzz/cs3这个作业的目标第10次-创建一个在线网站http://zclwwq.gitee.io/resume......
  • 一维数组与二维数组的创建、初始化和储存
     一、一维数组1.数组的创建 数组是一组相同类型的集合。数组的创建方式:type_t  arr_name  [contest_n];//type_t是指数组的元素类型//const_n是一个常量表达式,用来指数组的大小介绍一下strlen和sizeof的区别strlen和sizeof没什么关联strlen是求字符串长度的,只能根据字符串......
  • PHP将数据表里的两个字段映射成对象的键和值
    $playersArray=DB::table('sign_up') ->select('user_id','nickname') ->where('order_id','=',$request->id) ->where('nickname','<>','') ->get() -&g......
  • winform 使用了invoke还是报错 线程间操作无效: 从不是创建控件“Form2”的线程访问它
    winform开发中,遇到“线程间操作无效:从不是创建控件“Form2”的线程访问它”,明明使用了网上说的this.invoke,怎么还是会报这个错误呢?代码如下,由于是测试configureAwait功能时发现的,所以带了它的一些使用 privateasyncvoidbutton7_Click(objectsender,EventArgse)//点......