欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Ningx代碼研究(二)

系統(tǒng) 2096 0

內(nèi)存分配相關(guān)

系統(tǒng)功能封裝

內(nèi)存相關(guān)的操作主要在 os/unix/ngx_alloc.{h,c} 和 core/ngx_palloc.{h,c} 下

其中 os/unix/ngx_alloc.{h,c} 封裝了最基本的內(nèi)存分配函數(shù),是對c原有的malloc/free/memalign 等原有的函數(shù)的封裝,對應(yīng)的函數(shù)為:

  • ngx_alloc 使用malloc分配內(nèi)存空間
  • ngx_calloc 使用malloc分配內(nèi)存空間,并且將空間內(nèi)容初始化為0
  • ngx_memalign 返回基于一個(gè)指定的alignment大小的數(shù)值為對齊基數(shù)的空間
  • ngx_free 對內(nèi)存的釋放操作

ngx的內(nèi)存池

為了方便系統(tǒng)模塊對內(nèi)存的使用,方便內(nèi)存的管理,nginx自己實(shí)現(xiàn)了進(jìn)程池的機(jī)制來進(jìn)行內(nèi)存的分配和釋放, 首先nginx會在特定的生命周期幫你統(tǒng)一建立內(nèi)存池,當(dāng)需要進(jìn)行內(nèi)存分配的時(shí)候統(tǒng)一通過內(nèi)存池中的內(nèi)存進(jìn)行分配,最后nginx會在適當(dāng)?shù)臅r(shí)候釋放內(nèi)存池的資源,開發(fā)者只要在需要的時(shí)候?qū)?nèi)存進(jìn)行申請即可,不用過多考慮內(nèi)存的釋放等問題,大大提高了開發(fā)的效率。

內(nèi)存池的主要結(jié)構(gòu)為:

    
      //ngx_palloc.h
    
    
    
    
      struct
    
    
       ngx_pool_s 
    
    
      {
    
    
      
? ? ngx_pool_data_t ? ? ? d
    
    
      ;
    
    
      
? ? size_t ? ? ? ? ? ? ? ?max
    
    
      ;
    
    
      
? ? ngx_pool_t ? ? ? ? ? 
    
    
      *
    
    
      current
    
    
      ;
    
    
      
? ? ngx_chain_t ? ? ? ? ?
    
    
      *
    
    
      chain
    
    
      ;
    
    
      
? ? ngx_pool_large_t ? ? 
    
    
      *
    
    
      large
    
    
      ;
    
    
      
? ? ngx_pool_cleanup_t ? 
    
    
      *
    
    
      cleanup
    
    
      ;
    
    
      
? ? ngx_log_t ? ? ? ? ? ?
    
    
      *
    
    
      log
    
    
      ;
    
    
    
    
      };
    
    
    
    
      //ngx_core.h
    
    
    
    
      typedef
    
    
    
    
      struct
    
    
       ngx_pool_s ? ? ? ?ngx_pool_t
    
    
      ;
    
    
    
    
      typedef
    
    
    
    
      struct
    
    
       ngx_chain_s ? ? ? ngx_chain_t
    
    
      ;
    
  

下面是我簡單畫的一個(gè)圖來描述這個(gè)結(jié)構(gòu):

link :? http://www.flickr.com/photos/rainx/3765612584/sizes/o/

下面解釋一下主要的幾個(gè)操作:

    
      // 創(chuàng)建內(nèi)存池
    
    
      
ngx_pool_t 
    
    
      *
    
    
      ngx_create_pool
    
    
      (
    
    
      size_t size
    
    
      ,
    
    
       ngx_log_t 
    
    
      *
    
    
      log
    
    
      );
    
  

大致的過程是創(chuàng)建使用 ngx_alloc 分配一個(gè)size大小的空間, 然后將? ngx_pool_t* ?指向這個(gè)空間, 并且初始化里面的成員, 其中

    
      p
    
    
      ->
    
    
      d
    
    
      .
    
    
      last
    
    
    
    
      =
    
    
    
    
      (
    
    
      u_char 
    
    
      *)
    
    
       p 
    
    
      +
    
    
    
    
      sizeof
    
    
      (
    
    
      ngx_pool_t
    
    
      );
    
    
    
    
      // 初始指向 ngx_pool_t 結(jié)構(gòu)體后面
    
    
      
p
    
    
      ->
    
    
      d
    
    
      .
    
    
      end
    
    
    
    
      =
    
    
    
    
      (
    
    
      u_char 
    
    
      *)
    
    
       p 
    
    
      +
    
    
       size
    
    
      ;
    
    
    
    
      // 整個(gè)結(jié)構(gòu)的結(jié)尾后面
    
    
      
p
    
    
      ->
    
    
      max 
    
    
      =
    
    
    
    
      (
    
    
      size 
    
    
      <
    
    
       NGX_MAX_ALLOC_FROM_POOL
    
    
      )
    
    
    
    
      ?
    
    
       size 
    
    
      :
    
    
       NGX_MAX_ALLOC_FROM_POOL
    
    
      ;
    
    
    
    
      // 最大不超過 NGX_MAX_ALLOC_FROM_POOL,也就是getpagesize()-1 大小
    
  

其他大都設(shè)置為null或者0

    
      // 銷毀內(nèi)存池
    
    
    
    
      void
    
    
       ngx_destroy_pool
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      );
    
  

遍歷鏈表,所有釋放內(nèi)存,其中如果注冊了clenup(也是一個(gè)鏈表結(jié)構(gòu)), 會一次調(diào)用clenup 的 handler 進(jìn)行清理。

    
      // 重置內(nèi)存池
    
    
    
    
      void
    
    
       ngx_reset_pool
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      );
    
  

釋放所有l(wèi)arge段內(nèi)存, 并且將d->last指針重新指向 ngx_pool_t 結(jié)構(gòu)之后(和創(chuàng)建時(shí)一樣)

    
      // 從內(nèi)存池里分配內(nèi)存
    
    
    
    
      void
    
    
    
    
      *
    
    
      ngx_palloc
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ,
    
    
       size_t size
    
    
      );
    
    
    
    
      void
    
    
    
    
      *
    
    
      ngx_pnalloc
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ,
    
    
       size_t size
    
    
      );
    
    
    
    
      void
    
    
    
    
      *
    
    
      ngx_pcalloc
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ,
    
    
       size_t size
    
    
      );
    
    
    
    
      void
    
    
    
    
      *
    
    
      ngx_pmemalign
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ,
    
    
       size_t size
    
    
      ,
    
    
       size_t alignment
    
    
      );
    
  

ngx_palloc的過程一般為,首先判斷待分配的內(nèi)存是否大于 pool->max的大小,如果大于則使用 ngx_palloc_large 在 large 鏈表里分配一段內(nèi)存并返回, 如果小于測嘗試從鏈表的 pool->current 開始遍歷鏈表,嘗試找出一個(gè)可以分配的內(nèi)存,當(dāng)鏈表里的任何一個(gè)節(jié)點(diǎn)都無法分配內(nèi)存的時(shí)候,就調(diào)用 ngx_palloc_block 生成鏈表里一個(gè)新的節(jié)點(diǎn), 并在新的節(jié)點(diǎn)里分配內(nèi)存并返回, 同時(shí), 還會將pool->current 指針指向新的位置(從鏈表里面pool->d.failed小于等于4的節(jié)點(diǎn)里找出) ,其他幾個(gè)函數(shù)也基本上為 ngx_palloc 的變種,實(shí)現(xiàn)方式大同小異

    
      // 釋放指定的內(nèi)存
    
    
      
ngx_int_t ngx_pfree
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ,
    
    
    
    
      void
    
    
    
    
      *
    
    
      p
    
    
      );
    
  

這個(gè)操作只有在內(nèi)存在large鏈表里注冊的內(nèi)存在會被真正釋放,如果分配的是普通的內(nèi)存,則會在destory_pool的時(shí)候統(tǒng)一釋放.

    
      // 注冊cleanup回叫函數(shù)(結(jié)構(gòu)體)
    
    
      
ngx_pool_cleanup_t 
    
    
      *
    
    
      ngx_pool_cleanup_add
    
    
      (
    
    
      ngx_pool_t 
    
    
      *
    
    
      p
    
    
      ,
    
    
       size_t size
    
    
      );
    
  

這個(gè)過程和我們之前經(jīng)常使用的有些區(qū)別, 他首先在傳入的內(nèi)存池中分配這個(gè)結(jié)構(gòu)的空間(包括data段), 然后將為結(jié)構(gòu)體分配的空間返回, 通過操作返回的ngx_pool_cleanup_t結(jié)構(gòu)來添加回叫的實(shí)現(xiàn)。 ( 這個(gè)過程在nginx里面出現(xiàn)的比較多,也就是 xxxx_add 操作通常不是實(shí)際的添加操作,而是分配空間并返回一個(gè)指針,后續(xù)我們還要通過操作指針指向的空間來實(shí)現(xiàn)所謂的add )

下面是內(nèi)存操作的一些例子 demo/basic_types/mem_op.c

    
      #include
    
    
    
    
      <stdio.h>
    
    
    
    
      #include
    
    
    
    
      "ngx_config.h"
    
    
    
    
      #include
    
    
    
    
      "ngx_conf_file.h"
    
    
    
    
      #include
    
    
    
    
      "nginx.h"
    
    
    
    
      #include
    
    
    
    
      "ngx_core.h"
    
    
    
    
      #include
    
    
    
    
      "ngx_string.h"
    
    
    
    
      #include
    
    
    
    
      "ngx_palloc.h"
    
    
    
    
      volatile
    
    
       ngx_cycle_t ?
    
    
      *
    
    
      ngx_cycle
    
    
      ;
    
    
    
    
      void
    
    
      
ngx_log_error_core
    
    
      (
    
    
      ngx_uint_t level
    
    
      ,
    
    
       ngx_log_t 
    
    
      *
    
    
      log
    
    
      ,
    
    
       ngx_err_t err
    
    
      ,
    
    
      
? ? ? ? ? ? 
    
    
      const
    
    
    
    
      char
    
    
    
    
      *
    
    
      fmt
    
    
      ,
    
    
    
    
      ...)
    
    
    
    
      {
    
    
    
    
      }
    
    
    
    
      typedef
    
    
    
    
      struct
    
    
       example_s 
    
    
      {
    
    
      
? ? 
    
    
      int
    
    
       a
    
    
      ;
    
    
      
? ? 
    
    
      char
    
    
      *
    
    
       b
    
    
      ;
    
    
    
    
      }
    
    
       example_t
    
    
      ;
    
    
    
    
      int
    
    
       main
    
    
      ()
    
    
    
    
      {
    
    
      
? ? ngx_pool_t 
    
    
      *
    
    
      pool
    
    
      ;
    
    
      
? ? example_t
    
    
      *
    
    
       exp
    
    
      ;
    
    
      
? ? 
    
    
      char
    
    
      *
    
    
       s
    
    
      ;
    
    
      

? ? pool 
    
    
      =
    
    
       ngx_create_pool
    
    
      (
    
    
      5000
    
    
      ,
    
    
       NULL
    
    
      );
    
    
      
? ? printf
    
    
      (
    
    
      "available pool regular pool free size is %d now\n"
    
    
      ,
    
    
    
    
      (
    
    
      ngx_uint_t
    
    
      )
    
    
    
    
      (
    
    
      pool
    
    
      ->
    
    
      d
    
    
      .
    
    
      end
    
    
    
    
      -
    
    
       pool
    
    
      ->
    
    
      d
    
    
      .
    
    
      last
    
    
      ));
    
    
      
? ? exp 
    
    
      =
    
    
       ngx_palloc
    
    
      (
    
    
      pool
    
    
      ,
    
    
    
    
      sizeof
    
    
      (
    
    
      example_t
    
    
      ))
    
    
    
    
      ;
    
    
      
? ? s 
    
    
      =
    
    
       ngx_palloc
    
    
      (
    
    
      pool
    
    
      ,
    
    
    
    
      sizeof
    
    
      (
    
    
      "hello,world"
    
    
      ));
    
    
      
? ? printf
    
    
      (
    
    
      "available pool regular pool free size is %d now\n"
    
    
      ,
    
    
    
    
      (
    
    
      ngx_uint_t
    
    
      )
    
    
    
    
      (
    
    
      pool
    
    
      ->
    
    
      d
    
    
      .
    
    
      end
    
    
    
    
      -
    
    
       pool
    
    
      ->
    
    
      d
    
    
      .
    
    
      last
    
    
      ));
    
    
      
? ? exp
    
    
      ->
    
    
      a 
    
    
      =
    
    
    
    
      1
    
    
      ;
    
    
      
? ? exp
    
    
      ->
    
    
      b 
    
    
      =
    
    
       s
    
    
      ;
    
    
      
? ? strcpy
    
    
      (
    
    
      s
    
    
      ,
    
    
    
    
      "hello,world"
    
    
      );
    
    
      
? ? printf
    
    
      (
    
    
      "pool max is %d\n"
    
    
      ,
    
    
       pool
    
    
      ->
    
    
      max
    
    
      );
    
    
      
? ? printf
    
    
      (
    
    
      "exp->a is %d, exp->b is %s\n"
    
    
      ,
    
    
       exp
    
    
      ->
    
    
      a
    
    
      ,
    
    
       exp
    
    
      ->
    
    
      b
    
    
      );
    
    
      
? ? ngx_destroy_pool
    
    
      (
    
    
      pool
    
    
      );
    
    
      
? ? 
    
    
      return
    
    
    
    
      0
    
    
      ;
    
    
    
    
      }
    
  

編譯運(yùn)行結(jié)果

    
      gcc ?
    
    
      -
    
    
      c 
    
    
      -
    
    
      O 
    
    
      -
    
    
      pipe ?
    
    
      -
    
    
      O 
    
    
      -
    
    
      W 
    
    
      -
    
    
      Wall
    
    
    
    
      -
    
    
      Wpointer
    
    
      -
    
    
      arith 
    
    
      -
    
    
      Wno
    
    
      -
    
    
      unused
    
    
      -
    
    
      parameter 
    
    
      -
    
    
      Wunused
    
    
      -
    
    
      function
    
    
    
    
      -
    
    
      Wunused
    
    
      -
    
    
      variable 
    
    
      -
    
    
      Wunused
    
    
      -
    
    
      value 
    
    
      -
    
    
      Werror
    
    
    
    
      -
    
    
      g 
    
    
      -
    
    
      I 
    
    
      ../../../
    
    
      objs
    
    
      /
    
    
    
    
      -
    
    
      I 
    
    
      ../../
    
    
      os
    
    
      /
    
    
      unix
    
    
      /
    
    
       mem_op
    
    
      .
    
    
      c 
    
    
      -
    
    
      I
    
    
      ../../
    
    
      core
    
    
      /
    
    
    
    
      -
    
    
      I
    
    
      ../../
    
    
      event
    
    
      /
    
    
    
    
      -
    
    
      I
    
    
      ../../
    
    
      os
    
    
      /
    
    
    
    
      -
    
    
      o mem_op
    
    
      .
    
    
      o
?gcc 
    
    
      -
    
    
      o mem_op mem_op
    
    
      .
    
    
      o 
    
    
      ../../../
    
    
      objs
    
    
      /
    
    
      src
    
    
      /
    
    
      core
    
    
      /
    
    
      ngx_
    
    
      {
    
    
      string
    
    
      ,
    
    
      palloc
    
    
      }.
    
    
      o 
    
    
      ../../../
    
    
      objs
    
    
      /
    
    
      src
    
    
      /
    
    
      os
    
    
      /
    
    
      unix
    
    
      /
    
    
      ngx_alloc
    
    
      .
    
    
      o 
    
    
      -
    
    
      lcrypt 
    
    
      -
    
    
      lpcre 
    
    
      -
    
    
      lcrypto 
    
    
      -
    
    
      lz
rainx@rainx
    
    
      -
    
    
      laptop
    
    
      :~/
    
    
      land
    
    
      /
    
    
      nginx
    
    
      -
    
    
      0.7
    
    
      .
    
    
      61
    
    
      /
    
    
      src
    
    
      /
    
    
      demo
    
    
      /
    
    
      basic_types$ 
    
    
      ./
    
    
      mem_op 
available pool regular pool free size 
    
    
      is
    
    
    
    
      4960
    
    
       now
available pool regular pool free size 
    
    
      is
    
    
    
    
      4940
    
    
       now
pool max 
    
    
      is
    
    
    
    
      4960
    
    
      
exp
    
    
      ->
    
    
      a 
    
    
      is
    
    
    
    
      1
    
    
      ,
    
    
       exp
    
    
      ->
    
    
      b 
    
    
      is
    
    
       hello
    
    
      ,
    
    
      world
    
  

Ningx代碼研究(二)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美亚洲理伦电影毛片在线播放 | 亚洲精品视频在线 | 久久久网站亚洲第一 | 久久亚洲国产欧洲精品一 | 无线日本视频精品 | 黄色视屏免费观看 | 日本高清在线观看视频 | 久久国产精品免费网站 | 成人国产在线观看 | 中文久久 | 国产成人精品一区二区三区视频 | 日韩乱视频 | 国产高清xxxsexvideo | 高清中文字幕免费观在线 | 1级毛片 | 色在线观看视频 | 意大利av在线 | 第四色播日韩AV第一页 | 密室逃脱第一季免费观看完整在线 | 久9久9精品视频在线观看 | 亚洲精品aⅴ | 亚洲精品久久久久一区二区 | 久久蜜桃亚洲一区二区 | 亚洲网站在线观看 | 国产色婷婷精品综合在线观看 | 久久精品国产99久久6动漫亮点 | 久久色亚洲 | 视频一区二区不卡 | 91xxx在线观看 | 日韩精品久久久久久久电影99爱 | 日本亚洲精品色婷婷在线影院 | 麻豆视频秘密入口 | 精品国产AV色一区二区深夜久久 | 国产在线小视频 | 操操操日日日干干干 | 久久中文字幕免费 | 自拍偷拍亚洲欧美 | 久久国内精品自在自线400部o | 欧美精品中文字幕久久二区 | 国产一区二区三区久久久久久久久 | 精品伊人 |