ngnix:共享内存

来源:互联网 发布:中行校园淘宝卡骗局 编辑:程序博客网 时间:2024/05/21 19:50

总览

众所周知,共享内存是linux下进程之间通信的重要手段。ngnix也使用了共享内存的机制。
本博客简要以描述ngnix利用共享内存的流程为主线,渐渐展开了对ngnix对共享内存的使用的更多细节。
  • 主要参考 深入剖析ngnix(P46):我开始感受到这本书写的精妙之处,短小精干,有时觉得字字珠玉
  • nginx源码分析-共享内存
  • Nginx内存管理及数据结构浅析–共享内存的实现
  • nginx源码分析—全局变量ngx_cycle的初始化
  • Nginx源码分析-启动初始化过程(一)
  • Nginx启动初始化过程(二)

流程

  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的字段的具体含义。

0 0
原创粉丝点击