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 における共有メモリの使用プロセスは通常マスタープロセスによって作成され、ワーカープロセスは継承によってメモリポインタを取得します。
ngx_shmem の使用に関しては、ngx_event_module_init() のいくつかのフラグメントを参照できます。コードのこの部分では、さまざまな状態 (受け入れ/読み取り/書き込みなど) のリクエストを記録するために共有メモリにいくつかの変数を作成します。 ) 量を計算し、ngx_event_module のいくつかの主要なイベント エントリでこれらの変数に対して加算および減算の統計演算を実行します。すべてのワーカー プロセスの現在のリクエスト ステータスに関する統計を実装します。
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 の最後のインターフェイスは操作を示します。プールはすでにロックを取得しています。 ngx_slab_pool_t 構造には ngx_shmtx_t ミューテックスがあり、複数のプロセスが同時にプールにアクセスする同時シナリオを同期するために使用されます。 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 のリロード プロセス中に共有メモリが再適用されるかどうかを制御することに言及する価値があります。
ngx_init_cycle() 関数は長いため、このプロセスは /* create Shared Memory */ コメントまたはcycle->shared_memory オブジェクトを検索して関連するコードを表示することで確認できます。
以上がnginxで共有メモリを使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。