首页 运维 nginx nginx中的共享内存如何使用

nginx中的共享内存如何使用

May 14, 2023 pm 03:55 PM
nginx

ngx_shmem的使用

ngx_shmem.c/h文件只是对mmap()/munmap()系统调用或者shmget()/shmdt()的一个很简单的封装。实现了ngx风格的基础库,可以申请和释放一段连续的共享内存空间。一般用于固定长度的共享数据使用,使用过程中数据长度固定不会伸缩。

typedef struct {
  u_char   *addr;
  size_t    size;
  ...
} ngx_shm_t;
ngx_int_t ngx_shm_alloc(ngx_shm_t *shm);
void ngx_shm_free(ngx_shm_t *shm);
登录后复制

在ngxin中共享内存的使用流程,一般是由master进程创建,worker进程通过继承的方式获得内存指针。

关于ngx_shmem的使用,可以参考ngx_event_module_init()中部分片段,这部分代码在共享内存中创建了若干个变量,用于记录各个状态(accepted/reading/writing...)的请求数量,并在ngx_event_module中的几个关键事件入口对这几个变量进行加减统计操作。实现统计所有worker进程当前的请求状态。

shm.size = size;
ngx_str_set(&shm.name, "nginx_shared_zone");
shm.log = cycle->log;

if (ngx_shm_alloc(&shm) != ngx_ok) {
  return ngx_error;
}

shared = shm.addr;
...
ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
ngx_stat_waiting = (ngx_atomic_t *) (shared + 9 * cl);
登录后复制

关于这个功能的更多细节,可以查看代码中的ngx_stat_stub宏定义相关代码与ngx_http_stub_status_module。

ngx_slab的使用

ngx_shmem是一层极简的封装,实现了共享内存的基本功能。但我们程序中大部分的场景共享数据并不会一个固定大小的结构,而更多是像ngx_array、ngx_list、ngx_queue、ngx_rbtree这类大小可以变化的数据结构。

我们期望能有像ngx_pool_t一样可以动态申请释放空间一个内存池。ngx_slab正是一个这样的结构体,原理上与系统的malloc()有相识之处都是通过一系列算法实现对一段段内存片段的申请与释放。只不过ngx_slab操作的对象是基于ngx_shmem的共享内存。

先看一下ngx_slab的接口

typedef struct {
  ngx_shmtx_t    mutex;
  ...
  void       *data; /* 一般存放从pool中申请获得的根数据地址(pool中第一个申请的数据接口) */
  void       *addr; /* 使用ngx_shmem申请获得的共享内存基地址 */
} ngx_slab_pool_t;

void ngx_slab_init(ngx_slab_pool_t *pool);
void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_calloc(ngx_slab_pool_t *pool, size_t size);
void *ngx_slab_calloc_locked(ngx_slab_pool_t *pool, size_t size);
void ngx_slab_free(ngx_slab_pool_t *pool, void *p);
void ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p);
登录后复制

可以看到接口并不复杂,alloc与calloc的区别在于是否对申请获得的内存段清零,_locked结尾的接口表示操作的pool已经是获取到锁的。在ngx_slab_pool_t的结构体有一个ngx_shmtx_t的互斥锁用于同步多进程同时访问pool的并发场景。注意ngx_slab_alloc()会先获取锁、然后申请空间、最后释放锁。而ngx_slab_alloc_locked()则直接申请空间,认为程序已经在其他逻辑中获得锁了。

在nginx的开发中使用ngx_shmem一般需要遵循以下初始化流程:

  • 模块在配置解析过程中调用ngx_shared_memory_add()接口,注册一段共享内存。提供共享内存大小与内存初始化的回调函数。

  • 框架在ngx_init_cycle()中使用ngx_shmem申请内存,并初始化ngx_slab,然后回调模块注册的初始化函数

  • 模块使用ngx_slab的申请/是否接口

在这个流程中,涉及到ngx_shared_memory_add()接口与对应的ngx_shm_zone_t结构体。

struct ngx_shm_zone_s {
  void           *data;
  ngx_shm_t         shm;
  ngx_shm_zone_init_pt   init;
  void           *tag;
  void           *sync;
  ngx_uint_t        noreuse; /* unsigned noreuse:1; */
};
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
  size_t size, void *tag);
登录后复制

其中值得一提的是noreuse属性,这个属性控制了在nginx的reload过程中是否会重新申请共享内存。

由于关于ngx_init_cycle()函数较长,这个流程可以通过查找/* create shared memory */这个注释或者cycle->shared_memory这个对象查看相关代码。

以上是nginx中的共享内存如何使用的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章

仓库:如何复兴队友
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热门文章标签

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

tomcat服务器怎么让外网访问 tomcat服务器怎么让外网访问 Apr 21, 2024 am 07:22 AM

tomcat服务器怎么让外网访问

nginx启动命令和停止命令是什么 nginx启动命令和停止命令是什么 Apr 02, 2024 pm 08:45 PM

nginx启动命令和停止命令是什么

thinkphp怎么运行 thinkphp怎么运行 Apr 09, 2024 pm 05:39 PM

thinkphp怎么运行

tomcat和nginx有哪些区别 tomcat和nginx有哪些区别 Dec 27, 2023 pm 05:07 PM

tomcat和nginx有哪些区别

Welcome to nginx!怎么解决? Welcome to nginx!怎么解决? Apr 17, 2024 am 05:12 AM

Welcome to nginx!怎么解决?

phpmyadmin怎么注册 phpmyadmin怎么注册 Apr 07, 2024 pm 02:45 PM

phpmyadmin怎么注册

nodejs项目怎么部署到服务器 nodejs项目怎么部署到服务器 Apr 21, 2024 am 04:40 AM

nodejs项目怎么部署到服务器

访问网站出现nginx怎么解决 访问网站出现nginx怎么解决 Apr 02, 2024 pm 08:39 PM

访问网站出现nginx怎么解决

See all articles