ACE框架提供了一个内存分配器模板,并且提供了(仅且)一个模板实例,基于共存内存的内存分配器。这个共存内存分配器模板实例在ACE框架应用于,基于内存映射的进程通讯,以及进程间同步等。

ACE内存分配器模板ACE_Malloc_T定义了这样一个分配器,它使用了三个组件,同步锁<ACE_LOCK>,内存(池)管理器<ACE_CB>以及内存服务<ACE_MEM_POOL_1>。

ACE框架用于IPC的分配器模板实例ACE_MEM_SAP::MALLOC_TYPE,绑定了这三个组件为:进程锁ACE_Process_Mutex,内存(池的)块管理器ACE_PI_Control_Block,以及内存映射服务ACE_MMAP_Memory_Pool。

虽然ACE_MMAP_Memory_Pool的名字包含了内存池一词,但是它只负责于如何使用系统内存管理服务进行整体内存索取,分配器只有一小部分接口对内存服务进行代理,分配器其余接口全部由ACE_PI_Control_Block提供功能服务。分配器ACE_Malloc_T使用ACE_MMAP_Memory_Pool向系统索取整体内存,在这一大块内存上使用ACE_PI_Control_Block提供内存块分配服务。

下面是ACE_MMAP_Memory_Pool的主要功能的类图

分配器的主要功能组件为ACE_PI_Control_Block,它实现了分配器的内存块管理功能,它将由ACE_MMAP_Memory_Pool索取到的内存页面进行统一的块管理服务,也就是我们所理解的分配器内存管理服务。分配器接口提供两种管理服务,一种是分配和释放(calloc,malloc,release),另一种是通过名字绑定(bind,unbind)向外公布。

ACE_PI_Control_Block使用了两个链表分别支持分配器的两种功能服务,分别对应为空闲块链表和命名块链表,其中空闲块链表是环链表,链表结尾指向链表头。内存块的分配和释放管理,应用了ACE_Malloc_Header头,将所有内存块进行管理,空闲的块被链入到空闲块链表。分配时将大于需要尺寸的空闲块进行拆分使用。命名块管理,将分配出去的内存,以名字绑定的方式,链入到共同可以访问的链表,以使其它进程可以从链表中搜索出来并访问。使用相同映射内存池的分配器,从空闲链表中分配内存块,但是分配出去的内存块离开了共同访问的区域,要共享到其它进程,必须使用名称绑定并放入到一个共同可以访问的区域,这就是命名块链表。这里必须注意的是,被绑定的块一定是相同分配器分配出来的块。绑定的名称,分配器会在绑定函数中,为名称跟随命名绑定节点一起分配空间,位置紧接在命名绑定节点后面,命名绑定节点的名字用位置无关引用指向这个空间的位置,并将名字复制到这里。这时被绑定的块重新回到了分配器的管理之中,必须要解除绑定之后才可以释放。否则会带来跨进程的灾难。

ACE_PI_Control_Block提供链表服务是基于位置无关的,P(osition)I(ndepent)。由于分配器模板实例是一个进程间共享的分配器,分配的内存块映射在各自进程的地址空间中,并不可以使用直接指针来进行进程共享访问,必须通过一种手段来达到目的。ACE框架使用了这样一种指针代理引用,ACE_Based_Pointer,用于位置无关引用。这个指针代理引用并不储存直接指针,而通过偏移量来间接存储内存块的地址。内存块位于映射内存的相对位置(偏移量)不会因为内存映射在不同的地址空间而发生变化。同样,这个指针代理引用必须是由相同的分配器分配出来的,不能够是栈上的对象或其它堆分配器分配出来的对象。同理,分配器被进程共享访问的所有的一切都必须存放在相同的映射内存中,我们的分配器通过ACE_MMAP_Memory_Pool打开相同的映射内存。而分配器中的核心部件ACE_PI_Control_Block,它的所有包括它自身都必须构建在映射内存上。

在位置无关的ACE_Based_Pointer计算地址时,即计算出目标的地址时,这里隐含了一点,this指针是存在着变化的,在不同的映射空间中,this指针发生了平移delta。但是与原点(映射的基地址)的距离是不变的,所以不论在那一个进程上如何映射,只要用this减去距离base_offset_就可以得到映射的基地址。

base_offset_ = this - base;

代入进程1的this1与base1得到base_offset = this1 - base1。

内存在进程2的映射基地址为base2,可能与进程1映射基地址不一致,存在一个变化delta = base1 - base2。

代入进程2的base2后有 base_offset_ = this - (base1 - delta),可以得到this = this1 - delta,就是进程2的this2,也就是平移后的值。

尽管我们看到的代码为base = this - base_offset_,感觉不到this在不同的进程映射空间中发生了平移,但实际运行时我们用平移后的this求值得出也就是平移后的映射基地址。

ACE框架 基于共享内存的分配器的更多相关文章

  1. ACE框架 基于共享内存的分配器 (算法设计)

    继承上一篇<ACE框架 基于共享内存的分配器设计>,本篇分析算法部分的设计. ACE_Malloc_T模板定义了这样一个分配器组件 分配器组件聚合了三个功能组件:同步组件ACE_LOCK, ...

  2. ACE框架 基于共享内存的进程间通讯

    ACE框架将基于共享内存的进程间通讯功能,如其它IO组件或IPC组件一样,设计成三个组件.流操作组件ACE_MEM_Stream,连接器组件ACE_MEM_Connector,以及接收连接组件ACE_ ...

  3. (原创)[.Net] 进程间通信框架(基于共享内存)——SimpleMMF

    一.前言 进程间通信技术的应用非常广泛,在Windows下常用的实现方式有:管道.Socket.消息.本地文件.共享内存等,每种方式都有各自适应的场景. 在进行大数据交换时,最优的方式便是共享内存. ...

  4. Unix IPC之基于共享内存的计数器

    目的 本文主要实现一个基于共享内存的计数器,通过父子进程对其访问. 本文程序需基于<<Unix网络编程-卷2>>的环境才能运行.程序中大写开头的函数为其小写同名函数的包裹函数, ...

  5. 撸代码--linux进程通信(基于共享内存)

    1.实现亲缘关系进程的通信,父写子读 思路分析:1)首先我们须要创建一个共享内存. 2)父子进程的创建要用到fork函数.fork函数创建后,两个进程分别独立的执行. 3)父进程完毕写的内容.同一时候 ...

  6. 基于共享内存、信号、命名管道和Select模型实现聊天窗口

    问题模型 A.B两个进程通过管道通信,A 进程每次接收到的数据通过共享内存传递给A1进程显示,同理,B进程每次接收到的数据通过共享内存传递给B1进程显示: 对于A.B 进程,采用ctrl+c(实际为S ...

  7. vector存入共享内存(了解)

    昨天在上篇blog里描写了如何把STL容器放到共享内存里去,不过由于好久不写blog,发觉词汇组织能力差了很多,不少想写的东西写的很零散,今天刚好翻看自己的书签,看到一篇挺老的文章,不过从共享内存到S ...

  8. Qt之进程间通信(共享内存)

    简述 上一节中,我们分享下如何利用Windows消息机制来进行不同进程间的通信.但是有很多局限性,比如:不能跨平台,而且必须两个进程同时存在才可以,要么进程A发了消息谁接收呢? 下面我们来分享另外一种 ...

  9. h.264并行解码算法2D-Wave实现(基于多核非共享内存系统)

    在<Scalable Parallel Programming Applied to H.264/AVC Decoding>书中,作者基于双芯片18核的Cell BE系统实现了2D-Wav ...

随机推荐

  1. i春秋DMZ大型靶场实验(一)内网拓展

    更具提示 先下载工具包 ip  172.16.12.226  打开bp 进行代理发现 整个页面 没有请求 没有其页面通过 御剑,dir ,hscan   进行目录爆破未发现有用信息    对当前页面进 ...

  2. 百万年薪python之路 -- 面向对象之:类空间问题以及类之间的关系

    面向对象之:类空间问题以及类之间的关系 1.从空间角度研究类 1.何处添加对象属性 class A: def __init__(self,name): self.name = name def fun ...

  3. 拒绝黑盒应用-Spring Boot 应用可视化监控

    图文简介 逻辑关系 效果演示 快速开始 1.Spring Boot 应用暴露监控指标[版本 1.5.7.RELEASE] 首先,添加依赖如下依赖: <dependency> <gro ...

  4. tp5底层源码分析之------tp5.1类的自动加载机制

    tp框架作为国内主流框架,目前已经发布了6.0版本,相当于3.*版本是进行了重构,今天我们从源码的角度来研究下tp5.1自动加载的实现 作为单入口框架,从入口文件看起,入口文件在public/下,那么 ...

  5. LeetCode 十月份题目汇总

    开源地址:点击该链接 前言 十月份共有60道题目,全部属于 Easy 难度的,所以公众号中分享出来的并不多,只是挑了一些感觉还可以的才分享了出来,这60道题目我按照不同类别进行了分类整理,所有源码以及 ...

  6. LeetCode 二叉树的层次遍历

    第102题 给定一个二叉树,返回其按层次遍历的节点值. (即逐层地,从左到右访问所有节点). 例如: 给定二叉树: [3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 ...

  7. 为啥不能#define private public了?

    今天在写一个单元测试的时候出现了如下编译错误: 以前用gtest为了测试业务代码里的private函数和变量,一直是在单元测试代码通过#define private public这样的trick达到测 ...

  8. python:__name__的使用

    1.python中__name__是什么意思? 很多python的初学者可能都会遇到一个问题:__name__是什么意思? 在刚开始学习python的时候,我们总会看到这样一句代码: if __nam ...

  9. ORCLE 创建表空间,用户,赋予角色以及授权

    1.创建表空间MMS_DATA --创建表空间和数据库文件dbf CREATE TABLESPACE MMS_DATA DATAFILE 'D:\ORADATA\ORCL\MMS_DATA.DBF' ...

  10. 宋宝华:关于Ftrace的一个完整案例

    本文系转载,著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 作者: 宋宝华 来源: 微信公众号linux阅码场(id: linuxdev) Ftrace简介 Ftrace是Lin ...