在开辟好的共享内存内进行alloc/free的函数集

来源:chinaunix 作者:hightman
  
通常情况类似于内存池的资料比较多, 但之前开发东西在多进程/多线程混合的情况下寻求缓存解决方案时, 采用了共享内存.

而能对共享内存进行动态再分配的库有一个称之为 libmm 的模块, 但资料很少, 没有采用它. 后来我自己从 eAccelerator
(php的一个缓存扩展) 中找到一个 mm.c , 对它进行了简化和修改, 生成了一个我自己在用的 mm.c/mm.h 现在发布如下,

供有需要的参考, 但应该特别注意的是, 我这里申请的共享内存是一个匿名的内存映射, 只能共享于有亲属关系的进程中, 因
而可以在内存中再直接存放指针数据, 这一点比较方便.

而如果想用在无关系的进程之间, 那必须对代码进行修改, 支持有名的 mmap 或 IPC-shm 以及 IPC-sem 的, 并且在
mmap() 时指定同主进程相当的起始地址, 这个做法非常不值得推荐, mmap() 的起始捆绑地址一般应当由系统进行分配比较好.

好了, 代码如下, 供有需要或有兴趣的参考, 内存申请是由一个线性链表来管理的, 应当能满足大部分应用了

1. mm.h
/**
Libmm replacement used by cache design of FTPHP-searchd
Some source codes cut from eAccelerator/PHP

共享内存管理, 改自 eAccelerator 中的 mm.c, 采用 sem 信号量加锁, 线程安全!
使用时包含 mm.h 这个头文件即可, 数据类型 MM 就是这块共享内存的操作句柄类型.

常用 API 介绍:
1. MM *mm_create(size_t size);
   创建 size (单位bytes) 大小的共享内存空间(此为匿名mmap, 用于父子关系之间的进程)
   成功返回 MM 指针, 失败返回 NULL

2. void mm_destroy(MM *mm);
   销毁 mm, 它同时销毁所有的信号量锁, 多进程模型中只允许一次调用, 子进程退出时
   不必调用该函数, 以免破解整个全局的 mm 结构.

3. mm_lock(MM *mm); mm_unlock(MM *mm);
   对整个 mm 进行加锁或解锁.
   注意: 在 mm_malloc 和 mm_free 内部隐蔽地调用了 mm_lock/mm_unlock, 所以务必
         不能已加锁代码段里使用 mm_malloc/mm_free, 否则会造成死锁, 应当改用
         mm_malloc_nolock/mm_free_nolock

4. mm_lock1(MM *mm); mm_unlock1(MM *mm); ... mm_lock4(MM *mm); mm_unlock4(MM *mm);
   ... 这 4 组加锁/解锁之间互不影响, 可用于各类区间操作需加锁时使用.

5. void *mm_malloc(MM *mm, size_t size);
   void mm_free(MM *mm, void *p);

   申请和释放内存, 带全局锁

6. void *mm_malloc_nolock(MM *mm, size_t size);
   void mm_malloc_free(MM *mm, void *p);
   同上, 但不上锁


罕用的 API:
1. size_t mm_size(MM *mm);
   获取 mm 在创建时的 size.

2. int mm_protect(MM *mm, int mode);
   保护 mm , 内部调用 mprotect()
   mode 值为 MM_PROT_NONE, MM_PROT_READ, MM_PROT_WRITE, MM_PROT_EXEC 的组合

3. size_t mm_maxsize(MM *mm); size_t mm_avaiable(MM *mm);
   分别返回当前能申请到的最大内存长度和当前可用内存空间余额

4. size_t mm_sizeof(MM *mm, void *p);
   如果 p 为 mm_malloc 申请的内存, 则该调用可以返回申请时的长度

$Id: mm.h,v 1.3 2009/05/12 16:01:25 hightman Exp $
*/



#ifndef __FTPHP_MM_20090527_H__
#define    __FTPHP_MM_20090527_H__

#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef MM
#define    MM void
#endif

#define    MM_SEM_NUM        5
#define    mm_lock(x)        _mm_lock(x,0)
#define    mm_unlock(x)    _mm_unlock(x,0)
#define    mm_lock1(x)        _mm_lock(x,1)

时间:2009-06-13 20:29 来源:chinaunix 作者:hightman 原文链接

好文,顶一下
(1)
50%
文章真差,踩一下
(1)
50%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量