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. c语言1博客作业02

    c语言1博客作业02 这个作业属于哪个课程 C语言程序设计 这个作业的要求在哪 [作业要求](https://edu.cnblogs.com/campus/zswxy/SE2019-2/homewor ...

  2. 远程桌面连接(mstsc)

    目录 1. 序言 2. 准备工作 3. 内网远程连接(以mstsc的方式) 4. 问题---凭据不工作 5. 外网远程连接(mstsc) 6. 结语 更新时间:2019.09.10 1. 序言 有时候 ...

  3. human_pose_estimation_demo的再进一步研究

    这次研究的主要是速度问题,后来还获得了其它方面的收获. 1.原始的抽帧       对于这样一个问题,想提高速度,能够想到的最简单.最直接的方法就是“抽帧”.比如添加一个计数器 这里,只有当Sumof ...

  4. 实战SpringCloud响应式微服务系列教程(第九章)使用Spring WebFlux构建响应式RESTful服务

    本文为实战SpringCloud响应式微服务系列教程第九章,讲解使用Spring WebFlux构建响应式RESTful服务.建议没有之前基础的童鞋,先看之前的章节,章节目录放在文末. 从本节开始我们 ...

  5. 知否知否,VS Code 不止开源

    VS Code, 昨夜始于“开源”,如今“开源”深处渡. 读者看到这句话,也许会有疑惑,为什么两个“开源”都加上了双引号? 其实是笔者有意为之,因为这个两个“开源”的意义有着很大的差别,第一个“开源” ...

  6. 获得shell的几种姿势

    windows提权 1.通过sqlmap连接mysql获取shell (1)直接连接数据库 sqlmap.py -d "mysql://root:123456@127.0.0.1:3306/ ...

  7. activeMQ 安装及启动异常处理

    一.环境: [root@centos_6 ~]# cat /etc/system-release CentOS release 6.5 (Final) [root@centos_6 ~]# uname ...

  8. 【XSY2558】圆上的蚂蚁 Ants on circle

    Description L个点围成一个圆. 我们选定任意一个点作为原点, 则每个点的坐标为从原点顺时针走到这个点的距离. 圆上有N只蚂蚁, 分别被编号为1到N. 开始时, 第ii只蚂蚁在坐标为Xi的点 ...

  9. 强大的CompletableFuture

    引子 为了让程序更加高效,让CPU最大效率的工作,我们会采用异步编程.首先想到的是开启一个新的线程去做某项工作.再进一步,为了让新线程可以返回一个值,告诉主线程事情做完了,于是乎Future粉墨登场. ...

  10. 爬虫之selenium爬取斗鱼主播图片

    这是我GitHub上简单的selenium介绍与简单使用:https://github.com/bwyt/spider/tree/master/selenium%E5%9F%BA%E7%A1%80 & ...