learn nginx - 共享内存 - 小记

可以先看下:STL - 内存分配 - 内存池

程序中有个生存周期和进程一样长的变量,ngx_cycle_t。这个类型的变量会从父进程传递给子进程。

该类型中与共享内存相关的变量为:

// file: ngx_cycle.h
struct ngx_cycle_s {
  ...
  ngx_list_t  shared_memory;  // 以链表的形式来管理共享内存,每个元素是ngx_shm_zone_t类型
  ...
};

// file: ngx_cycle.h
struct ngx_shm_zone_s {
    void                     *data;     // init初始化命令需要的入参
    ngx_shm_t                 shm;      // 实际的共享内存对象
    ngx_shm_zone_init_pt      init;     // init handler
    void                     *tag;      // 共享内存块的所有者,通常是模块的名字
    void                     *sync;     // todo: unknown
    ngx_uint_t                noreuse;  /* unsigned  noreuse:1; */
};

// file: ngx_shmem.h
typedef struct {
    u_char      *addr;     // 共享内存起始地址,转换成ngx_slab_pool_t使用
    size_t       size;     // 共享内存大小
    ngx_str_t    name;     // 该共享内存大名字
    HANDLE       handle;   // CreateFileMapping返回的handle
    ngx_log_t   *log;      // 日志相关
    ngx_uint_t   exists;   /* unsigned  exists:1;  */
} ngx_shm_t;

上面中ngx_slab_pool_tslab内存管理器相关。简单介绍,包括缓存和对齐两点。缓存就是,提前申请好内存并对内存做好划分形成内存池,当需要使用内存的时候,直接从已经申请并划分好的内存池里取出一块合适大小的内存即可,而内存释放也是吧内存返还给Nginx的内存池;对齐则意味着内存的申请,总是按2的幂次方进行,即内存大小总是为8,16,32,64等。

在初始化的过程中,各自的模块初始化的时候,会根据特定的大小,对共享内存进行初始化。如:

ngx_http_limit_req_zone() -> ngx_shared_memory_add() -> ngx_list_push()

通过函数ngx_slab_allocngx_shm_t.addr中申请内存空间,如果内存池中的内存不够,会返回错误。

nginx共享内存管理图

参考资料

posted @ 2020-09-18 09:35  grassofsky  阅读(226)  评论(0)    收藏  举报