iis服务器助手广告广告
返回顶部
首页 > 资讯 > 服务器 >nginx共享内存的机制详解
  • 204
分享到

nginx共享内存的机制详解

2024-04-02 19:04:59 204人浏览 薄情痞子
摘要

目录1 共享内存申请2 共享内存实现原理2.1 共享内存组织2.2 slab共享内存管理机制2.3 slab与ngx_shm_zone_t 关系3 共享内存应用1 共享内存申请 共享

1 共享内存申请

共享内存申请比较简单,这里采用的是linux系统共享内存分配的函数实现的。

#include <sys/ipc.h>
#include <sys/shm.h>


ngx_int_t
ngx_shm_alloc(ngx_shm_t *shm)
{
    int  id;

    id = shmget(IPC_PRIVATE, shm->size, (SHM_R|SHM_W|IPC_CREAT));

    if (id == -1) {
        ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
                      "shmget(%uz) failed", shm->size);
        return NGX_ERROR;
    }

    ngx_log_debug1(NGX_LOG_DEBUG_CORE, shm->log, 0, "shmget id: %d", id);

    shm->addr = shmat(id, NULL, 0);

    if (shm->addr == (void *) -1) {
        ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno, "shmat() failed");
    }

    if (shmctl(id, IPC_RMID, NULL) == -1) {
        ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
                      "shmctl(IPC_RMID) failed");
    }

    return (shm->addr == (void *) -1) ? NGX_ERROR : NGX_OK;
}


void
ngx_shm_free(ngx_shm_t *shm)
{
    if (shmdt(shm->addr) == -1) {
        ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
                      "shmdt(%p) failed", shm->addr);
    }
}

2 共享内存实现原理

2.1 共享内存组织

共享内存的管理工作是在:ngx_cycle内完成,主要是利用一个list进行组织。
首先是ngx_list组织形式,采用的是将多个ngx_list_part单元串行组成的链表;同时每个ngx_list_part是由多个ngx_shm_zone_t组成构成。这样做的一个好处就是一次预先分配一个元素组,只有当第一个元素组用完才会申请新的元素组。可以达到减少频繁分配的问题。

在这里插入图片描述

这里需要展开对应ngx_shm_zone单元的介绍:
首先是用户定义自己的数据结构并存入data中;第二部分是初始化函数,用户获取到ngx_shm_zone_t 共享内存单元的时候需要注册自己数据结构的初始化函数,其中zone返回是当前的共享内存的数据,而data返回的是上一次初始化的数据即历史数据;tag存放的是创建共享内存的模块;ngx_shm_t共享内存基本信息包括地址,大小,名称,log输出位置等。

typedef struct {
    u_char      *addr;//共享内存地址
    size_t       size;//大小
    ngx_str_t    name;//名称
    ngx_log_t   *log;
    ngx_uint_t   exists;   
} ngx_shm_t;
typedef ngx_int_t (*ngx_shm_zone_init_pt) (ngx_shm_zone_t *zone, void *data);
struct ngx_shm_zone_s {
    void                     *data;//用户数据
    ngx_shm_t                 shm; //共享内存结构体
    ngx_shm_zone_init_pt      init;//用户数据的初始化函数
    void                     *tag;//创建的模块
    ngx_uint_t                noreuse;  
};

初始化函数具体调用位置是在创建完共享内存后即进行初始化ngx_init_cycle函数中进行:

在这里插入图片描述

2.2 slab共享内存管理机制

slab内存分配方式是共享内存的管理机制,主要是利用最优选择的思路,当我们申请内存块时只会返回恰好符合请求大小的内存块。基本原理是把内存按照4k一页分成若干页,将每页放置不同大小的内存块,然后利用bitmap在页首进行标识内存块是否被使用。只需要变量bitmap查找空闲的内存块从而提高查找效率。

在这里插入图片描述

将存放不同大小的内存块的页面利用链表顺序串联,这样利用slots数组存放链表的首页。这样可以直接根据要分配内存大小进行寻址。

在这里插入图片描述

这里还有一个小操作提高查找空闲内存,当一个页面没有空闲的内存块时需要从队列中脱离变成一个单独的节点。

2.3 slab与ngx_shm_zone_t 关系

整体的初始化动作是在ngx_init_zone_pool函数进行:利用shm中addr存放slab_pool对象,并完成slab的初始化动作。

ngx_slab_pool_t  *sp;
sp = (ngx_slab_pool_t *) zn->shm.addr;
sp->addr = zn->shm.addr;
ngx_slab_init(sp);

3 共享内存应用

共享内存的使用场景,这里分析ssl模块的共享内存使用方法,可以推广到其他模块使用。
首先是是进行共享内存的ngx_shm_zone_t分配,这是一个比较简单的操作,从共享内存返回一块空闲的shm_zone.

ngx_shm_zone_t  *shm_zone;//共享内存单元
ngx_conf_t *cf;//ngx配置
ngx_str_t   name;//共享内存名称
ngx_int_t    n;//分配共享内存的大小
ngx_module_t  ngx_stream_ssl_module;//使用共享内存的模块,防止模块间重名
scf->shm_zone = ngx_shared_memory_add(cf, &name, n,&ngx_stream_ssl_module);//从
if (scf->shm_zone == NULL) {
     return NGX_CONF_ERROR;
 }
//初始化函数设置
 scf->shm_zone->init = ngx_ssl_session_cache_init;

初始化函数:data返回的是上一次分配的数据,如果存在直接返回。否则先取出slab_pool进程分配操作调用ngx_slab_alloc分配一个内存块大小,可以是数据结构。这里分配的是一个红黑树结构,分配完成后就可以直接初始化红黑树。

ngx_int_t
ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
{
    size_t                    len;
    ngx_slab_pool_t          *shpool;
    ngx_ssl_session_cache_t  *cache;

    if (data) {
        shm_zone->data = data;
        return NGX_OK;
    }
	//获取slab_pool
    shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;

    if (shm_zone->shm.exists) {
        shm_zone->data = shpool->data;
        return NGX_OK;
    }
	//为数据分配slab内存块
    cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t));
    if (cache == NULL) {
        return NGX_ERROR;
    }
	//赋值到slab_pool管理
    shpool->data = cache;
    shm_zone->data = cache;
	//红黑树数据初始化
    ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel,
                    ngx_ssl_session_rbtree_insert_value);
	//队列初始化
    ngx_queue_init(&cache->expire_queue);
	//设置log
    len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len;
	//为log分配共享内存
    shpool->log_ctx = ngx_slab_alloc(shpool, len);
    if (shpool->log_ctx == NULL) {
        return NGX_ERROR;
    }
	//写log
    ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z",
                &shm_zone->shm.name);

    shpool->log_nomem = 0;

    return NGX_OK;
}

到此这篇关于Nginx共享内存的机制详解的文章就介绍到这了,更多相关nginx共享内存内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: nginx共享内存的机制详解

本文链接: https://www.lsjlt.com/news/143199.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • nginx共享内存的机制详解
    目录1 共享内存申请2 共享内存实现原理2.1 共享内存组织2.2 slab共享内存管理机制2.3 slab与ngx_shm_zone_t 关系3 共享内存应用1 共享内存申请 共享...
    99+
    2024-04-02
  • 详解Android Ashmem匿名共享内存
    目录1. 简述2. 创建 MemoryFile 和 数据写入3. 将文件描述符传递到其他进程4. 在其他进程接收 FileDescriptor 并读取数据1. 简述 Android...
    99+
    2024-04-02
  • Linux共享内存实现机制的示例分析
    这篇文章将为大家详细讲解有关Linux共享内存实现机制的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Linux共享内存实现机制的详解内存共享: 两个不同进程A、B共享内存的意思是,同一块物理内存...
    99+
    2023-06-09
  • SQL Server内存机制详解
    1.前言 对于数据库引擎来说,内存是一个性能提升的重要解决手段。把数据缓存起来,可以避免在查询或更新数据时花费多余的时间,而这时间通常是从磁盘获取数据时用来等待磁盘寻址的。把执行计划...
    99+
    2024-04-02
  • php进程通信之共享内存详细讲解
    目录常见进程通信方式system V共享内存php使用共享内存共享内存基本函数使用父子进程通信配合信号量使用非血缘关系进程共享内存通信共享内存的特性常见进程通信方式 system ...
    99+
    2024-04-02
  • OpenMP共享内存的并行编程框架入门详解
    目录简介认识 openmp 的简单易用性C 语言实现C++ 实现OpenMP 实现opnemp 基本原理积分例子总结简介 OpenMP 一个非常易用的共享内存的并行编程框架,它提供了...
    99+
    2022-11-16
    OpenMP 共享内存并行编程框架 OpenMP 入门
  • C++共享内存删除的陷阱
    文章转自微信公众号:CPP开发前沿 当进程结束使用共享内存区时,要通过函数 shmdt 断开与共享内存区的连接。该函数声明在 sys/shm.h 中,其原型如下:  int...
    99+
    2024-04-02
  • JS堆栈内存的运行机制详解
    目录栈内存 ECStack堆内存数据类型创建步骤在js引擎中对变量的存储主要有两个位置,堆内存和栈内存。栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、Str...
    99+
    2024-04-02
  • 如何理解Kubernetes中Pod间共享内存
    如何理解Kubernetes中Pod间共享内存,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一些公共服务组件在追求性能过程中,与业务耦合太紧,造成在制作基础镜像时,都会把这...
    99+
    2023-06-04
  • Linux系统共享内存该如何理解
    这篇文章主要为大家分析了Linux系统共享内存该如何理解的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“Linux系统共享内存该如何理解”的知识吧。共享内存在...
    99+
    2023-06-28
  • php共享内存的方法是什么
    在PHP中,可以使用共享内存来实现进程间的通信和数据共享。PHP提供了一个扩展模块,名为shmop,该模块允许我们创建和操作共享内存...
    99+
    2023-09-06
    php
  • 详解CLR的内存分配和回收机制
    一、CLR CLR:即公共语言运行时(Common Language Runtime),是中间语言(IL)的运行时环境,负责将编译生成的MSIL编译成计算机可以识别的机器码,负责资源...
    99+
    2024-04-02
  • 详解php内存管理机制与垃圾回收机制
    目录一、内存管理机制二、垃圾回收机制一、内存管理机制 先看一段代码: <?php //内存管理机制 var_dump(memory_get_usage());//获...
    99+
    2024-04-02
  • Python超详细讲解内存管理机制
    目录什么是内存管理机制一、引用计数机制二、数据池和缓存什么是内存管理机制 python中创建的对象的时候,首先会去申请内存地址,然后对对象进行初始化,所有对象都会维护在一 个叫做re...
    99+
    2024-04-02
  • win10 gpu共享内存和专有内存的区别是什么
    这篇“win10 gpu共享内存和专有内存的区别是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“win10 gpu共享内...
    99+
    2023-07-01
  • Python 并发编程中的数据共享:探索安全的共享机制
    介绍 在多线程或多进程的并发 Python 程序中,多个线程或进程可以同时访问和修改共享数据。这可能会导致数据竞争和不一致,从而破坏程序的完整性和正确性。因此,在并发编程中管理数据共享至关重要。 锁:互斥访问 锁提供了一种用于确保同一时...
    99+
    2024-02-18
    Python 并发编程 数据共享 线程安全 事件 队列
  • Linux进程共享内存的方法是什么
    这篇文章主要讲解了“Linux进程共享内存的方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux进程共享内存的方法是什么”吧!共享内存 IPC 原理共享内存进程间通信机制主要用...
    99+
    2023-06-28
  • C++共享内存删除的陷阱是怎样的
    C++共享内存删除的陷阱是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。当进程结束使用共享内存区时,要通过函数 shmdt 断开与共享内存区的连接。该函数声明在 sy...
    99+
    2023-06-26
  • Golang使用ttl机制保存内存数据方法详解
    目录获取当前时间数据结构Heap操作测试ttl容器Heap完整代码总结ttl(time-to-live) 数据存活时间,我们这里指数据在内存中保存一段时间,超过期限则不能被读取到,与...
    99+
    2023-03-08
    Go保存内存数据 Go ttl机制保存内存数据
  • 详解win7共享打印机给win10连接的方法
    目前在同个局域网下一般都是多台电脑共用一台打印机,特别是在公司环境中,这个时候就需要连接共享打印机使用了。有网友不知道win10怎样连接win7共享打印机,今天小编就教下大家win7共享打印机给win10连接的方法。具体的步骤如下:1、进入...
    99+
    2023-07-10
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作