菜鳥nginx源碼剖析數據結構篇(十一) 共享內存ngx_shm_tnginx
Author:Echo Chen(陳斌)數據結構
Email:chenb19870707@gmail.comapp
Blog:Blog.csdn.net/chen19870707ui
Date:Nov 14th, 2014spa
共享內存是Linux下提供的最基本的進程通訊方法,它經過mmap或者shmget系統調用在內存中建立了一塊連續的線性地址空間,而經過munmap或者shmdt系統調用釋放這塊內存,使用共享內存的好處是多個進程使用同一塊內存時,在任何一個進程修改了共享內存中的內容後,其它進程經過訪問這段內存就可以獲得內存變化。.net
頭文件:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_shmtx.h日誌
源文件:http://trac.nginx.org/nginx/browser/nginx/src/core/ngx_shmtx.ccode
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;
共享內存申請mmap:blog
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則是欲取消的內存大小
共享內存的主要操做有如下幾種:
共享內存的分配 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: }
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: }
《深刻理解Ngxin》