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. php无限遍历目录-修正版

    最近在能php目录操作,搞了一个目录无限遍历: 使用的函数有: isset()判断某个变量是否定义 chdir() 将当前目录改变为指定的目录. opendir() 打开目录. readdir()读取 ...

  2. Python进阶之“属性(property)”详解

    Python中有一个被称为属性函数(property)的小概念,它可以做一些有用的事情.在这篇文章中,我们将看到如何能做以下几点: 将类方法转换为只读属性 重新实现一个属性的setter和getter ...

  3. C# 调用 Outlook发送邮件实例

    添加引用:Microsoft.Office.Interop.Outlook using System; using System.Collections.Generic; using System.L ...

  4. 【springMVC】简单的前后端数据交流

    最最常见两种,一则返回视图模板(文档),二则为json数据.就使用一个源代码文件来看看springmvc是怎么做到的. 1.UserController.java源代码文件 (这里额外的使用了fast ...

  5. jsoup: Java HTML Parser (类似jquery)

    jsoup is a Java library for working with real-world HTML. It provides a very convenient API for extr ...

  6. mysql5.x(<7) sql文件导入到5.7

    一.修改sql—model http://www.linuxidc.com/Linux/2016-09/135372.htm

  7. transition&transform,CSS中过度和变形的设置

    设置样式的过度效果transition-property: none/all; transition-duration:2s;运动时间,默认是0秒 transition-delay:0s; 延迟时间默 ...

  8. jquery checkbox勾选/取消勾选的诡异问题

    <form> 你爱好的运动是?<input type="checkbox" id="CheckedAll" />全选/全不选<br ...

  9. 最新为Phpstorm配置xdebug 进行断点调试

    额  ,曾经写过一个,现在发现不咋好使了 ,你说咋整,下载xdebug的时候 还得注意系统是32位还是64位,而且一堆下载文件不知道是哪个. 额,所以我现在发现有个更好的方法,啥也不下了 直接配把  ...

  10. jfinal 基本应用 --定时任务 QuartzPlugin

    jfinal 的定时器的使用: 项目中使用的maven管理器 1.导入要使用的包 2.添加Job类 配置参数 这个配置是jfinal-quartz 包中带的默认文档,即是默认加载的文档(其中还有一个q ...