Background

我们的多进程程序碰到一个需求:做key-value查询,然后拿获取到的value去做一些事情。这些key-value存储在很多词典文件中,数量级>10w,如果每个进程都加载一份,内存上是很浪费的,所以需要共享访问,看起来就像是一个IPC使用std::map的场景。有很多方法都可以选择,挑选几类比较下。

Socket

多进程程序作为clients,加载词典提供查询服务的程序作为server,通过网络来交互,很好的避免了共享带来的资源竞争,架构上看是解耦的,细看一下交互过程,client首先send request,触发server查询词典,经过两次memcpy后将value送出,随后client也要经过两次memcpy,最后get response,性能上比较差。

SQLlite

同一sqllite db可以被多进程直接访问,性能相比socket要好的多了,但它的写操作是锁保护的,即同时只能有一个进程访问。sqllite是内存数据库,支持KeyValueDatabase,但根据sqllite官方公布的测试数据来看select性能并不理想

Memory-mapped file

内存映射文件是较理想的进程共享方法,这里是使用方法。我们的词典文件比较多也比较大,频繁的read/write必然会产生大量的系统调用和memory copy,这块可以用mmap来优化(详见)。词典文件内容仅仅从disk映射到了内存,从mmap到hash还需要把原始数据映射成hash,这块如果每个进程都要做一次,性能也好不到哪里。

Shm-hash

shm_hash本质是一个hash,它的时间复杂度也是O(1),设想我们给hash增加一个方法:

//从内存地址直接映射成hash
hash_int_from_memory(void *mem, unit32_t len)

这个方法看似不起眼,但却可以为我们提供避免重复构造hash的功能。

Final

用伪代码描述下shm_hash结合mmap在各个进程的构造过程

//******begin
//进程A将数据导入到hash
fd = fopen("hash.mmap");
lseek(fd);
ptr = mmap(fd);
hash_int_from_memory(ptr);
while(have) {
hash_add("key", "value");
}
//******end //******begin
//进程A将数据导入到hash
fd = fopen("hash.mmap");
hash_int_from_memory(ptr);
//******end

一个共享内存hash的更多相关文章

  1. Linux 驱动学习笔记05--字符驱动实例,实现一个共享内存设备的驱动

    断断续续学驱动,好不容易有空,做了段字符驱动的例子.主要还是跟书上学习在此记录下来,以后说不定能回过头来温故知新. 首先上驱动源码 gmem.c: /************************* ...

  2. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  3. linux 共享内存 shmat,shmget,shmdt,shmctl

    shmget int shmget(key_t key, size_t size, int flag);//开辟一段共享内存 key_t key :标识符的规则() size_t size :共享内存 ...

  4. linux进程间通信-共享内存

    转载:http://www.cnblogs.com/fangshenghui/p/4039720.html 一 共享内存介绍 共享内存可以从字面上去理解,就把一片逻辑内存共享出来,让不同的进程去访问它 ...

  5. Linux进程间通信之共享内存

    一,共享内存  内核管理一片物理内存,允许不同的进程同时映射,多个进程可以映射同一块内存,被多个进程同时映射的物理内存,即共享内存.  映射物理内存叫挂接,用完以后解除映射叫脱接. 1,共享内存的特点 ...

  6. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  7. php 共享内存

    共享内存主要用于进程间通信 php中的共享内存有两套扩展可以实现 1.shmop  编译时需要开启 --enable-shmop 参数 实例: $shm_key = ftok(__FILE__, 't ...

  8. C扩展 从共享内存shm到memcache外部内存

    引言 - ipc - shm 共享内存 本文会通过案例了解ipc 的共享内存机制使用, 后面会讲解C 如何使用外部内存服务memcached. 好先开始了解 linux 共享内存机制. 推荐先参看下面 ...

  9. Linux共享内存(一)

    inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...

随机推荐

  1. Zabbix 3.0.3 SQL Injection

    Zabbix version 3.0.3 suffers from a remote SQL injection vulnerability. ============================ ...

  2. UVa 11300 Spreading the Wealth(有钱同使)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New ...

  3. boost 编译,windows平台

    下载Boost及生成bjam.exe文件 到Google网站搜索下载boost_1.52版本库,下载完成后,解压到X:下,这个地址自己随便定义.在解压的文件中搜索build.bat文件,把它所在的目录 ...

  4. 20160817_Redis配置操作

    ZC: 主要是 做一些配置,使得 java程序能够访问到 redis服务器,主要内容为:ZC: ①.redis服务端服务 重启的命令ZC: ②.取消绑定 本地IP的配置,使得 所有本网段局域网机器都能 ...

  5. [转载]Eclipse提示No java virtual machine

    第一次运行Eclipse,经常会提示下面的问题:... No java virtual machine  was found after searching the follwing location ...

  6. iOS修改手机定位(非越狱任意位置)

    利用开发者的一些调试功能,我们可以修改非越狱的苹果手机定位,模拟任意位置. 经测试,此方法仅限开发者调试使用,并不能长时间修改手机定位. 1. 首先需要了解一些坐标系的知识 iOS,原生坐标系为 WG ...

  7. CentOS7 增加tomcat 启动,停止,使用systemctl进行配置

    1,centos7 使用 systemctl 替换了 service命令 参考:redhat文档: https://access.redhat.com/documentation/en-US/Red_ ...

  8. 并发编程 17—— Lock

    Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...

  9. 读javascript高级程序设计03-函数表达式、闭包、私有变量

    一.函数声明和函数表达式 定义函数有两种方式:函数声明和函数表达式.它们之间一个重要的区别是函数提升. 1.函数声明会进行函数提升,所以函数调用在函数声明之前也不会报错: test(); functi ...

  10. 分布式系统开发的一些相关理论基础——CAP、ACID、BASE

    本文主要讲述分布式系统开发的一些相关理论基础. 一.ACID 事务的四个特征: 1.Atomic原子性 事务必须是一个原子的操作序列单元,事务中包含的各项操作在一次执行过程中,要么全部执行成功,要么全 ...