基于共享内存的异步无锁IPC类库 Traffic-SHM 源码阅读

Traffic-SHM是一个使用Java实现的共享内存通信库,支持非阻塞算法,适用于高吞吐量、低延迟的实时系统。文章详细介绍了其内存映射、内存对齐、字节顺序、数据结构和并发控制等方面,特别是通过sun.misc.Unsafe实现的CAS操作确保并发安全性。
摘要由CSDN通过智能技术生成

全文目录

Trafic-SHM特点:

一、内存映射

二、内存对齐

三、字节顺序

四、数据结构

五、并发控制

六、关键代码

内存映射类MappedFile

数据结构类Queue

元数据类Metadata

数据块类Block

块标识类ACK

七、互斥原理


github项目地址:https://github.com/peptos/traffic-shm

 

Trafic-SHM特点:

1. Traffic-SHM使用sun.misc.Unsafe和FileChannel提供共享内存机制的纯Java实现,需要JDK 1.6+。共享内存是进程间通信的有效机制。 内存映射文件提供动态内存管理功能,允许应用程序以与将虚拟地址空间的物理内存共享段相同的方式访问磁盘上的文件。

2. Traffic-SHM使用非阻塞算法,实现多生产者/单消费者并发队列,可用于构建具有高吞吐量和低延迟的实时系统。

3. Traffic-SHM数据对齐方式为4字节对齐,字节顺序为大端模式。

4. Traffic-SHM提供一个OAOO(ONCE-AND-ONLY-ONCE)保证的FIFO队列。光标只能向前传送,一旦消息成功传递,消息就是AUTOMATIC ACKNOWLEDGMENT,这意味着一旦接收者接收到消息,就会确认消息。

 

一、内存映射

操作系统使用虚拟内存来进行内存管理。虚拟内存是一个抽象的概念,它为每个为应用进程提供了使用虚拟地址取代物理内存地址进行内存访问的功能。

操作系统通过将一个虚拟内存区域与一个磁盘上的普通文件关联起来,以初始化这个虚拟内存区域的内容,这个过程称为内存映射。Java语言中,可通过FileChannel类的map()方法进行操作,实现过程由操作系统的mmap()实现。

内存映射使用文件系统建立从用户空间直到可用文件系统页的虚拟内存映射。这样做有几个好处:

1. 用户进程把文件数据当作内存,所以无需发布read()或write()系统调用。

2. 当用户进程碰触到映射内存空间,缺页错误会自动产生,从而将文件数据从磁盘读进内存。如果用户修改了映射内存空间,相关页会自动标记为脏,随后刷新到磁盘,文件得到更新。

3. 操作系统的虚拟内存子系统会对页进行智能高速缓存,自动根据系统负载进行内存管理。

4. 数据总是按页对齐的,无需执行缓冲区拷贝。

5. 大型文件使用映射,无需耗费大量内存,即可进行数据拷贝。

 

 

 

二、内存对齐

1. 页对齐 操作系统对内存采用页式管理机制,对于用mmap()映射的普通文件来说,进程会在自己的地址空间新增一块空间,空间大小由mmap()的len参数指定。进程能够访问的有效地址大小取决于文件被映射部分的大小。超过这个空间大小,内核会根据超过的严重程度返回发送不同的信号给进程。示例如下:

因此,考虑到不同操作系统及处理器架构,内存映射文件的大小及mmap()映射的内存空间大小均需要按页大小进行对齐。

2. 数据类型对齐 简单来讲,数据类型对齐需要满足以下条件:数据所在的内存虚拟地址要能被这个数据的长度所整除。数据域单个数据块以4字节进行对齐。

 

三、字节顺序

不同的处理器架构使用不同的字节顺序存储数据,目前常见有大端小端两种存储方式。一个多位的整数将按照其存储地址的最低或最高字节排列,如果低位字节存放在内存的低地址端,高位字节存放在内存的高地址端,称为小端模式,反之为大端模式。

以0x0A0B0C0D为例:

小端模式:

1

2

3

4

0x0D

0x0C

0x0B

0x0A

大端模式:

1

2

3

4

0x0A

0x0B

0x0C

0x0D

为了保证在不同操作系统及处理器架构下的可移植性,Trafic-SHM约定按照大端模式存储数据

 

四、数据结构

如下图所示,队列由元数据域及数据域两部分组成,公共信息及读写位置指针在元数据域维护,数据块为数据域的最小单位(图有误,Block的顺序为ACK-Length-Payload)

同时为了节约内存空间,避免频繁映射造成的内存浪费,针对数据域采用了环形队列RingBuffer数据结构。

 

五、并发控制

可见性 为保证可见性,使用Unsafe的volatile方法对读写位置指针及ACK域进行操作。

原子性 为了保证在多生产者模式下的原子性,对ACK域的一个int类型先后进行了两次无符号short型填充。

 

六、关键代码

内存映射类MappedFile

关键成员:

类型

变量名

备注

RandomAccessFile

raf

随机读写文件

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值