js-shm: 高性能 Node.js 共享内存模块

js-shm: 高性能 Node.js 共享内存模块

什么是 js-shm

js-shm 是一个基于 Linux 共享内存机制实现的高性能 Node.js 模块,使用 node-addon-api 作为 C++ 接口层,为 Node.js 提供接近原生速度的跨进程通信能力。

核心特点

极致性能

  • 写入吞吐量:60+ GB/s(64KB 数据)
  • 读取吞吐量:60+ GB/s(复用 Buffer)
  • 往返延迟:< 10 μs(64KB 数据)

线程安全

  • 使用 POSIX 信号量(Semaphore)保护共享内存操作
  • 支持多进程并发读写,无数据竞争
  • 服务端/客户端模式,正确处理资源生命周期

实时通知

  • 后台轮询线程检测数据变化
  • 使用 ThreadSafeFunction 安全回调 JavaScript
  • 事件延迟 < 500 μs

技术架构

#mermaid-svg-95S4xYkd6WjhFDyt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-95S4xYkd6WjhFDyt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-95S4xYkd6WjhFDyt .error-icon{fill:#552222;}#mermaid-svg-95S4xYkd6WjhFDyt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-95S4xYkd6WjhFDyt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-95S4xYkd6WjhFDyt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-95S4xYkd6WjhFDyt .marker.cross{stroke:#333333;}#mermaid-svg-95S4xYkd6WjhFDyt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-95S4xYkd6WjhFDyt p{margin:0;}#mermaid-svg-95S4xYkd6WjhFDyt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-95S4xYkd6WjhFDyt .cluster-label text{fill:#333;}#mermaid-svg-95S4xYkd6WjhFDyt .cluster-label span{color:#333;}#mermaid-svg-95S4xYkd6WjhFDyt .cluster-label span p{background-color:transparent;}#mermaid-svg-95S4xYkd6WjhFDyt .label text,#mermaid-svg-95S4xYkd6WjhFDyt span{fill:#333;color:#333;}#mermaid-svg-95S4xYkd6WjhFDyt .node rect,#mermaid-svg-95S4xYkd6WjhFDyt .node circle,#mermaid-svg-95S4xYkd6WjhFDyt .node ellipse,#mermaid-svg-95S4xYkd6WjhFDyt .node polygon,#mermaid-svg-95S4xYkd6WjhFDyt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-95S4xYkd6WjhFDyt .rough-node .label text,#mermaid-svg-95S4xYkd6WjhFDyt .node .label text,#mermaid-svg-95S4xYkd6WjhFDyt .image-shape .label,#mermaid-svg-95S4xYkd6WjhFDyt .icon-shape .label{text-anchor:middle;}#mermaid-svg-95S4xYkd6WjhFDyt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-95S4xYkd6WjhFDyt .rough-node .label,#mermaid-svg-95S4xYkd6WjhFDyt .node .label,#mermaid-svg-95S4xYkd6WjhFDyt .image-shape .label,#mermaid-svg-95S4xYkd6WjhFDyt .icon-shape .label{text-align:center;}#mermaid-svg-95S4xYkd6WjhFDyt .node.clickable{cursor:pointer;}#mermaid-svg-95S4xYkd6WjhFDyt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-95S4xYkd6WjhFDyt .arrowheadPath{fill:#333333;}#mermaid-svg-95S4xYkd6WjhFDyt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-95S4xYkd6WjhFDyt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-95S4xYkd6WjhFDyt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-95S4xYkd6WjhFDyt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-95S4xYkd6WjhFDyt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-95S4xYkd6WjhFDyt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-95S4xYkd6WjhFDyt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-95S4xYkd6WjhFDyt .cluster text{fill:#333;}#mermaid-svg-95S4xYkd6WjhFDyt .cluster span{color:#333;}#mermaid-svg-95S4xYkd6WjhFDyt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-95S4xYkd6WjhFDyt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-95S4xYkd6WjhFDyt rect.text{fill:none;stroke-width:0;}#mermaid-svg-95S4xYkd6WjhFDyt .icon-shape,#mermaid-svg-95S4xYkd6WjhFDyt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-95S4xYkd6WjhFDyt .icon-shape p,#mermaid-svg-95S4xYkd6WjhFDyt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-95S4xYkd6WjhFDyt .icon-shape .label rect,#mermaid-svg-95S4xYkd6WjhFDyt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-95S4xYkd6WjhFDyt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-95S4xYkd6WjhFDyt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-95S4xYkd6WjhFDyt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Linux 内核
C++ 层
Node.js 进程
用户代码
JavaScript API
write/read/onData
SharedMemWrap
node-addon-api
sharedMem
send/recv
dev/shm 共享内存
SharedMemHeader
seq_count
data_len
data
POSIX Semaphore
信号量 共享内存 进程 B (消费者) 进程 A (生产者) 信号量 共享内存 进程 B (消费者) 进程 A (生产者) #mermaid-svg-UufNuNX0hvxUSwy2{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-UufNuNX0hvxUSwy2 .error-icon{fill:#552222;}#mermaid-svg-UufNuNX0hvxUSwy2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-UufNuNX0hvxUSwy2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-UufNuNX0hvxUSwy2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-UufNuNX0hvxUSwy2 .marker.cross{stroke:#333333;}#mermaid-svg-UufNuNX0hvxUSwy2 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-UufNuNX0hvxUSwy2 p{margin:0;}#mermaid-svg-UufNuNX0hvxUSwy2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UufNuNX0hvxUSwy2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UufNuNX0hvxUSwy2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-UufNuNX0hvxUSwy2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-UufNuNX0hvxUSwy2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-UufNuNX0hvxUSwy2 .sequenceNumber{fill:white;}#mermaid-svg-UufNuNX0hvxUSwy2 #sequencenumber{fill:#333;}#mermaid-svg-UufNuNX0hvxUSwy2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-UufNuNX0hvxUSwy2 .messageText{fill:#333;stroke:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UufNuNX0hvxUSwy2 .labelText,#mermaid-svg-UufNuNX0hvxUSwy2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .loopText,#mermaid-svg-UufNuNX0hvxUSwy2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-UufNuNX0hvxUSwy2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-UufNuNX0hvxUSwy2 .noteText,#mermaid-svg-UufNuNX0hvxUSwy2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-UufNuNX0hvxUSwy2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UufNuNX0hvxUSwy2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UufNuNX0hvxUSwy2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-UufNuNX0hvxUSwy2 .actorPopupMenu{position:absolute;}#mermaid-svg-UufNuNX0hvxUSwy2 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-UufNuNX0hvxUSwy2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-UufNuNX0hvxUSwy2 .actor-man circle,#mermaid-svg-UufNuNX0hvxUSwy2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-UufNuNX0hvxUSwy2 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 获取锁 锁定成功 write(data) 更新 seq_count 更新 data_len memcpy 数据 释放锁 解锁 获取锁 锁定成功 read(buffer) memcpy 到 buffer 释放锁 解锁
#mermaid-svg-8xZfrbPx4EfjSza8{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8xZfrbPx4EfjSza8 .error-icon{fill:#552222;}#mermaid-svg-8xZfrbPx4EfjSza8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8xZfrbPx4EfjSza8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8xZfrbPx4EfjSza8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8xZfrbPx4EfjSza8 .marker.cross{stroke:#333333;}#mermaid-svg-8xZfrbPx4EfjSza8 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8xZfrbPx4EfjSza8 p{margin:0;}#mermaid-svg-8xZfrbPx4EfjSza8 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster-label text{fill:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster-label span{color:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster-label span p{background-color:transparent;}#mermaid-svg-8xZfrbPx4EfjSza8 .label text,#mermaid-svg-8xZfrbPx4EfjSza8 span{fill:#333;color:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 .node rect,#mermaid-svg-8xZfrbPx4EfjSza8 .node circle,#mermaid-svg-8xZfrbPx4EfjSza8 .node ellipse,#mermaid-svg-8xZfrbPx4EfjSza8 .node polygon,#mermaid-svg-8xZfrbPx4EfjSza8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8xZfrbPx4EfjSza8 .rough-node .label text,#mermaid-svg-8xZfrbPx4EfjSza8 .node .label text,#mermaid-svg-8xZfrbPx4EfjSza8 .image-shape .label,#mermaid-svg-8xZfrbPx4EfjSza8 .icon-shape .label{text-anchor:middle;}#mermaid-svg-8xZfrbPx4EfjSza8 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8xZfrbPx4EfjSza8 .rough-node .label,#mermaid-svg-8xZfrbPx4EfjSza8 .node .label,#mermaid-svg-8xZfrbPx4EfjSza8 .image-shape .label,#mermaid-svg-8xZfrbPx4EfjSza8 .icon-shape .label{text-align:center;}#mermaid-svg-8xZfrbPx4EfjSza8 .node.clickable{cursor:pointer;}#mermaid-svg-8xZfrbPx4EfjSza8 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8xZfrbPx4EfjSza8 .arrowheadPath{fill:#333333;}#mermaid-svg-8xZfrbPx4EfjSza8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8xZfrbPx4EfjSza8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8xZfrbPx4EfjSza8 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xZfrbPx4EfjSza8 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8xZfrbPx4EfjSza8 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xZfrbPx4EfjSza8 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster text{fill:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 .cluster span{color:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8xZfrbPx4EfjSza8 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8xZfrbPx4EfjSza8 rect.text{fill:none;stroke-width:0;}#mermaid-svg-8xZfrbPx4EfjSza8 .icon-shape,#mermaid-svg-8xZfrbPx4EfjSza8 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8xZfrbPx4EfjSza8 .icon-shape p,#mermaid-svg-8xZfrbPx4EfjSza8 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8xZfrbPx4EfjSza8 .icon-shape .label rect,#mermaid-svg-8xZfrbPx4EfjSza8 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8xZfrbPx4EfjSza8 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8xZfrbPx4EfjSza8 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8xZfrbPx4EfjSza8 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 内存布局
seq_count

uint64_t
data_len

uint64_t
data

uint8_t\[\]

性能对比

操作 数据大小 吞吐量
写入 64KB 60+ GB/s
读取(复用 Buffer) 64KB 60+ GB/s
读取(每次分配) 64KB ~2 GB/s
往返延迟 64KB < 10 μs

使用场景

1. 多进程数据共享

javascript 复制代码
// 进程 A - 生产者
const { SharedMem } = require('./index');
const mem = new SharedMem('my_shared_data', 1024 * 1024, true);

setInterval(() => {
    const data = Buffer.from(JSON.stringify({ timestamp: Date.now() }));
    mem.write(data);
}, 100);
javascript 复制代码
// 进程 B - 消费者
const { SharedMem } = require('./index');
const mem = new SharedMem('my_shared_data', 1024 * 1024, false);

const buf = Buffer.alloc(1024 * 1024);
setInterval(() => {
    const len = mem.read(buf);
    const data = buf.slice(0, len);
    console.log(JSON.parse(data.toString()));
}, 100);

2. 事件驱动通信

javascript 复制代码
const { SharedMem } = require('./index');
const mem = new SharedMem('event_channel', 65536, true);

mem.onData((data) => {
    console.log('收到数据:', data.length, 'bytes');
});

mem.write(Buffer.from('Hello from js-shm!'));

3. 高性能数据管道

javascript 复制代码
const { SharedMem } = require('./index');
const mem = new SharedMem('data_pipeline', 1024 * 1024, true);

const readBuf = Buffer.alloc(1024 * 1024);

// 写入性能测试
const data = Buffer.alloc(65536, 'x');
const start = process.hrtime.bigint();
for (let i = 0; i < 10000; i++) {
    mem.write(data);
}
const end = process.hrtime.bigint();
const timeMs = Number(end - start) / 1000000;
console.log(`写入 625MB 耗时: ${timeMs.toFixed(2)}ms`);

安装与使用

bash 复制代码
# 安装依赖
npm install

# 编译 C++ 扩展
npm run build

# 运行测试
npm test

# 运行性能测试
npm run test:perf

项目结构

复制代码
js-shm/
├── binding.gyp          # node-gyp 配置
├── package.json         # npm 配置
├── index.js             # JavaScript 接口
├── plugs.cpp            # Node.js 插件入口
├── sharedMemWrap.hpp    # C++ 封装头文件
├── sharedMemWrap.cpp    # C++ 封装实现
├── test.js              # 单元测试
├── test_perf.js         # 性能测试
└── README.md            # 项目文档

性能测试结果

复制代码
=== 性能测试开始 ===

1. 写入吞吐量测试
--- 写入吞吐量测试 ---
  数据大小: 64 B, 迭代: 10000, 总数据: 625.00 KB
  耗时: 1.97 ms, 吞吐量: 309.45 MB/s

  数据大小: 64.00 KB, 迭代: 10000, 总数据: 625.00 MB
  耗时: 10.72 ms, 吞吐量: 58307.20 MB/s

2. 读取吞吐量测试
--- 读取吞吐量测试 (复用Buffer) ---
  数据大小: 64.00 KB, 迭代: 10000, 总数据: 625.00 MB
  耗时: 10.23 ms, 吞吐量: 61084.96 MB/s

3. 往返延迟测试
--- 往返延迟测试 ---
  数据大小: 64 B, 迭代: 10000
  平均延迟: 1.04 μs

为什么选择 js-shm

vs Redis

  • 无需网络开销,直接内存访问
  • 延迟降低 99%(从 ms 级降至 μs 级)
  • 无需部署额外服务

vs IPC / Socket

  • 共享内存是最快的进程间通信方式
  • 吞吐量提升 100x
  • 零拷贝数据传输

vs Node.js 原生 cluster

  • 真正的跨进程共享,不限于父子进程
  • 支持任意数量进程同时访问
  • 独立于 Node.js 运行时

技术细节

内存布局

cpp 复制代码
struct SharedMemHeader {
    uint64_t seq_count;    // 序列号,用于检测数据变化
    uint64_t data_len;     // 实际数据长度
    uint8_t data[0];       // 柔性数组,存储实际数据
};

线程安全机制

cpp 复制代码
class semaphore {
public:
    void lock() { sem_wait(p_sem__); }
    void unlock() { sem_post(p_sem__); }
};

size_t send(const uint8_t* data, size_t len) {
    smfLockGuard lck(m_smf__);  // RAII 自动加锁
    // 写入数据...
}

Node.js 回调机制

cpp 复制代码
napi_status status = m_tsfn__.NonBlockingCall(data, [](Napi::Env env, Napi::Function jsCallback, uint8_t* data) {
    Napi::Buffer<uint8_t> buffer = Napi::Buffer<uint8_t>::New(env, data, len);
    jsCallback.Call({buffer});
});

总结

js-shm 为 Node.js 提供了一个高性能、线程安全、易于使用的共享内存解决方案。无论是多进程数据共享、实时事件通信还是高性能数据管道,js-shm 都能满足您的需求。

项目地址 : https://gitee.com/galaxy_0/js-shm

相关推荐
笨蛋不要掉眼泪3 小时前
Java虚拟机:常用参数
java·开发语言·python
带娃的IT创业者3 小时前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc
2023自学中3 小时前
imx6ull 开发板 贪吃蛇, C++11 SDL2 无硬件GPU优化版
linux·c++
happy_0x3f3 小时前
前端应用的离线暂停更新策略
开发语言·前端·php
anscos3 小时前
为CUDA 代码引入静态分析
c++·工业软件·功能检测
众少成多积小致巨3 小时前
C++ 规范参考(中)
c++
小保CPP3 小时前
OpenCV C++基于AI模型的场景文本识别(OCR)
c++·人工智能·opencv·计算机视觉·ocr
shylyly_3 小时前
C++中的类型转换
开发语言·c++·匿名对象·隐式类型转换·拷贝优化
jinyishu_3 小时前
哈希表原理与开放定址法C++实现
c++·哈希算法·散列表