ngnix:共享内存

总览

众所周知,共享内存是linux下进程之间通信的重要手段。ngnix也使用了共享内存的机制。
本博客简要以描述ngnix利用共享内存的流程为主线,渐渐展开了对ngnix对共享内存的使用的更多细节。

流程

  1. 在配置文件中写清楚所需要的共享内存的信息
  2. ngnix启动,解析配置文件,以ngx_http_limit_req_module为例,它需要的共享内存以以下方式在配置文件中出现:

    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s

  3. ngnix解析到 2 中那段话,便调用处理函数 ngx_http_limit_req_zone()
  4. ngx_http_limit_req_zone()函数将调用shared_memor_add()函数
  5. shared_memor_add()函数 创建 结构体:ngx_shm_zone_t(含相关信息),将调用ngx_list_push()将其插入到一个全是共享内存的链表:cf->cycle->shared_memory
  6. 配置文件解析完成
  7. 在函数 ngx_init_cycle() 中开始遍历:cf->cycle->shared_memory,逐个创建和初始化的工作共享内存
  8. 创建由:ngx_shm_alloc()函数完成,根据系统的不同调用mmap和shmget
  9. 初始化:由ngx_init_zone_pool()函数来完成,主要完成两件事:互斥锁和初始化slab内存管理方式(ngx_slab_init()函数)
  10. 接着调用回调函数:shm_zone[i].init(&shm_zone[i], NULL)。这是在 5 中填写相关信息时候添加的函数。这个函数可以屏蔽掉 9 中的slab内存管理方式。

    以ngx_http_limit_req_module为例,调用的函数是:ngx_http_limit_req_init_zone()
    主要是根据自身模块的特别做一些处理。
    比如最终将共享内存的起始位置交给了:ngx_http_limit_req_ctx_t 结构体的*shpool->addr
    又比如:在9步中完成了slab内存管理方式的初始化,那么这里调用ngx_slab_alloc()函数完成了内存的具体的分配

  11. 结束

相关结构体

作为表示共享内存的变量,需要了解其含义:
typedef struct ngx_shm_zone_s  ngx_shm_zone_t;

typedef ngx_int_t (*ngx_shm_zone_init_pt) (ngx_shm_zone_t *zone, void *data);

struct ngx_shm_zone_s {
    void                     *data; //与shm.addr存在关系,可以作为是否处理化该共享内存的标记(待确认)
    ngx_shm_t                 shm;  //见下
    ngx_shm_zone_init_pt      init;//指向一个回调函数,见流程的10
    void                     *tag;//指向一个模块的ngx_module_t变量
    				  //这是为了区分不同模块的共享内存可以有相同的名字
    				  //但是靠这个tag变量来区分
};

typedef struct {
    u_char      *addr;//初始地址
    size_t       size;//共享内存的大小
    ngx_str_t    name;//共享内存的名字
    ngx_log_t   *log;
    ngx_uint_t   exists;   /* unsigned  exists:1;  */
} ngx_shm_t;

相关函数

往小了说,只有两个,存在于:src/os/unix/ngx_shmem.c 和src/os/unix/ngx_shmem.h
如下:
ngx_int_t ngx_shm_alloc(ngx_shm_t *shm); //分配内存
void ngx_shm_free(ngx_shm_t *shm);       //释放内存
看其名字也知道是什么含义,注意在实现的过程中:
必须要下列三个值有一个被赋值之后,才会调用相应的
  1. NGX_HAVE_MAP_ANON
  2. NGX_HAVE_MAP_DEVZERO
  3. NGX_HAVE_SYSVSHM

总结

通过这一次学习的总结,让我认识到:
  1. 共享内存与slab机制联系紧密,而且我觉得slab机制更重要,它关系到如何管理这个共享内存
  2. 共享内存与互斥锁也有紧密的关系:因为多线程对共享内存的访问涉及竞争,如何互斥的访问共享内存就需要互斥锁
  3. 突然发现,必须要ngnix启动过程的详细行为做一个大致的了解:比如 ngx_init_cycle() 函数具体做了什么。
  4. 必须对各个ngnix模块的分工做更多的了解,比如回答:这份源码是完成什么功能,什么模块调用其函数,需要其功能
  5. 配置文件的了解也是必须的。比如流程中2的字段的具体含义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值