zoukankan      html  css  js  c++  java
  • 菜鸟nginx源码剖析数据结构篇(十一) 共享内存ngx_shm_t[转]

    菜鸟nginx源码剖析数据结构篇(十一) 共享内存ngx_shm_t

    • Author:Echo Chen(陈斌)

    • Email:chenb19870707@gmail.com

    • Blog:Blog.csdn.net/chen19870707

    • Date:Nov 14th, 2014

      1.共享内存

      共享内存是Linux下提供的最基本的进程通信方法,它通过mmap或者shmget系统调用在内存中创建了一块连续的线性地址空间,而通过munmap或者shmdt系统调用释放这块内存,使用共享内存的好处是多个进程使用同一块内存时,在任何一个进程修改了共享内存中的内容后,其它进程通过访问这段内存就能够得到内存变化。

    • 2.源代码位置

      头文件:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_shmtx.h

      源文件:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_shmtx.c

      3.数据结构定义

      ngx_shm_t : 用于描述一块共享内存:

         1: typedef struct {
         2:     u_char      *addr;            //指向共享内存的起始地址
         3:     size_t       size;            //共享内存的长度
         4:     ngx_str_t    name;            //这块共享内存的名称
         5:     ngx_log_t   *log;             //记录日志的ngx_log_t对象
         6:     ngx_uint_t   exists;          //表示共享内存是否分配过的标志位,为1表示已经存在
         7: } ngx_shm_t;
    • 4.Linux 共享内存接口

       

      共享内存申请mmap:

         1: #include<sys/mman.h>
         2: void*mmap(void* start,size_t length,int prot,int flags,
         3: int fd,off_t offset);

      mmap可以将磁盘文件映射到内存中,直接操作内存时Linux内核将负责同步内存和磁盘文件中的数据,fd参数就执行需要同步的磁盘文件,而offset则代表从文件的这个偏移量处开始共享,Nginx没有使用这一特性。当flags参数中加入MAP_ANON或者MAP_ANONYMOUS参数时表示不适用文件映射方式,这时fd和offset参数就都没意义了,不需要传递了。Nginx中就不需要同步到磁盘。

      length参数就是将要在内存中开辟的线性地址空间大小

      port参数表示操作这段共享内存的方式(只读或者可读可写)

      start参数说明希望的共享内存起始地址,通常设为NULL

      共享内存释放munmap:

         1: #include<sys/mman.h>
         2: int munmap(void *start,size_t length);

      start所指的映射内存起始地址,参数length则是欲取消的内存大小

    • 5.共享内存的主要操作

    • 共享内存的主要操作有以下几种:

    • 共享内存的分配 ngx_shm_alloc
      共享内存的释放 ngx_shm_free

      5.1 共享内存的分配 ngx_shm_alloc

         1: ngx_int_t ngx_shm_alloc(ngx_shm_t *shm)
         2: {
         3:     //开辟一shm->size大小并且可读可写的共享内存,内存首地址放在shm->addr中
         4:     shm->addr = (u_char *) mmap(NULL, shm->size,
         5:                                 PROT_READ|PROT_WRITE,
         6:                                 MAP_ANON|MAP_SHARED, -1, 0);
         7:  
         8:     if (shm->addr == MAP_FAILED) {
         9:         ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
        10:                       "mmap(MAP_ANON|MAP_SHARED, %uz) failed", shm->size);
        11:         return NGX_ERROR;
        12:     }
        13:  
        14:     return NGX_OK;
        15: }
      •  5.2 共享内存释放 ngx_shm_free

         1: void
         2: ngx_shm_free(ngx_shm_t *shm)
         3: {
         4:     //使用ngx_shm_t中的addr和size调用munmap释放共享内存
         5:     if (munmap((void *) shm->addr, shm->size) == -1) {
         6:         ngx_log_error(NGX_LOG_ALERT, shm->log, ngx_errno,
         7:                       "munmap(%p, %uz) failed", shm->addr, shm->size);
         8:     }
         9: }
    • 6.参考

    • 《深入理解Ngxin》

  • 相关阅读:
    【原创】主机不能访问虚拟机CentOS7中的站点
    phpStudy中MySQL版本升级到5.7.17方法
    phpStudy for Linux (lnmp+lamp一键安装包)
    Linux的wget命令详解【转载】
    重置密码解决MySQL for Linux错误 ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
    mysql5.7密码过期ERROR 1862 (HY000): Your password has expired. To log in you must change
    电赛菜鸟营培训(二)——STM32F103CB之中断控制
    电赛菜鸟营培训(零)——Keil环境搭建
    电赛菜鸟营培训(一)——STM32F103CB之LED控制
    AppInventor学习笔记(四)——打地鼠应用学习
  • 原文地址:https://www.cnblogs.com/0x2D-0x22/p/4141310.html
Copyright © 2011-2022 走看看