内存业务[置顶] 高并发服务器的设计内存池的设计

题记:写这篇博客要主是加深自己对内存业务的认识和总结实现算法时的一些验经和训教,如果有错误请指出,万分感谢。

    typedef struct yumei_mem_buf_s yumei_mem_buf_t; typedef struct yumei_mem_pool_s yumei_mem_pool_t; struct yumei_mem_buf_s { int size; char *pos; char *data; yumei_mem_pool_t *pool; }; struct yumei_mem_pool_s { int size; char *data; char *last; yumei_mem_pool_t *next; yumei_mem_pool_t *current; }; yumei_mem_pool_t* yumei_mem_pool_create( int block_size, int block_num ); int yumei_mem_pool_free( yumei_mem_pool_t *pool ); yumei_mem_buf_t* yumei_mem_malloc( yumei_mem_pool_t *pool, int size ); int yumei_mem_buf_free( yumei_mem_buf_t *buf );

    在每个连接开始的时候,创立连接独一的内存池,存放IO数据,当要创立新业务时,创立业务内存池,业务处理完毕时释放内存池:

    typedef struct yumei_busi_s yumei_busi_t; struct yumei_busi_s { yumei_mem_pool_t *pool; ... ... } #define yumei_BUSI_MEM_BLOCL_SIZE 512 #define yumei_BUSI_MEM_BLOCK_NUM 32 yumei_busi_t* yumei_busi_create() { yumei_busi_t* busi; yumei_pool_t* pool; yumei_mem_buf_t* buf; int size; pool = yumei_mem_pool_create( yumei_BUSI_MEM_BLOCL_SIZE, yumei_BUSI_MEM_BLOCK_NUM ); if( !pool ){ return 0; } size = sizeof( yumei_busi_t ); buf = yumei_mem_buf_malloc( pool, size ); if( !buf ){ yumei_mem_pool_free( pool ); return 0; } busi = buf->data; return busi; } #define YUMEI_BUSI_ERROR -1 #define YUMEI_BUSI_OK 0 int yumei_busi_free( yumei_busi_t* busi ) { if( !busi ){ return YUMEI_BUSI_ERROR; } yumei_mem_pool_free( busi->pool ); return YUMEI_BUSI_OK; }

    有些时候业务比较简略,一个连接仅对应一个业务或多个业务不是并行执行,这样的情况下,就不再需要业务内存池了,可以直接用连接内存池:

    每日一道理
宽容,是一种坦荡,可以无私无畏,无拘无束,无尘无染。宽容,是一种豁达,是比海洋和天空更为博大的胸襟,是宽广和宽厚的叠加,延续和升华。宽容有度,宽容无价,宽以待人,这是人生处世的基本法则。

    

    yumei_busi_t* yumei_busi_create( yumei_conn_t* conn ) { yumei_busi_t* busi; yumei_pool_t* pool; yumei_mem_buf_t* buf; int size; pool = conn->pool; if( !pool ){ retur 0; } size = sizeof( yumei_busi_t ); buf = yumei_mem_buf_malloc( pool, size ); if( !buf ){ yumei_mem_pool_free( pool ); return 0; } busi = buf->data; return busi; } #define YUMEI_CONN_ERROR -1 #define YUMEI_CONN_OK 0 int yumei_conn_close( yumei_conn_t* conn ) { if( !conn ){ return YUMEI_CONN_ERROR; } yumei_mem_pool_free( conn->pool ); return YUMEI_CONN_OK; }

    

晓得内存池怎么用了,再来看看外部计划吧,pool 的四个元素里 size 对应 block_size, data和last 分别对应块的肇端地址和可分配地址,next和current分别对应下块内存池和当前可用内存池。

    

在一些通用的服务器上还会看到另一个元素:large。 这个是争对一些大内存的分配,当不清楚业务到底需要多大内存的时候,large往往是必须的,这样内存池结构就酿成这样:

    typedef struct yumei_mem_large_s yumei_mem_large_t; struct yumei_mem_large_s { char *data; int size; yumei_mem_large_t *next; } struct yumei_mem_pool_s { int size; char *data; char *last; yumei_mem_pool_t *next; yumei_mem_pool_t *current; yumei_mem_large_t *large; };

    

对于一些特别的业务,比如业务使用的内存巨细都牢固,且相近的时候,内存池就缩化成了牢固巨细的内存管理,实际上是很简略了,这样的内存池可以绑定在连接上,且用完不必释放,留待下条连接复用,进一步节省开销。

文章结束给大家分享下程序员的一些笑话语录: 不会,Intel会维持高利润,也会维持竞争局面,国外的竞争不是打死对方的那种。你看日本有尼康,佳能,索尼,都做相机,大家都过得很滋润。别看一堆厂,其实真正控制的是后面的那几个财团——有些竞争对手,后面其实是一家人。

--------------------------------- 原创文章 By
内存和业务
---------------------------------

原文地址:https://www.cnblogs.com/jiangu66/p/3102199.html