上記の続きです。
nginx はコンソール上で 1 つのプロセスとして実行されます。core/nginx.c の main メソッドを読んでください。これを注意深く読まないと、簡単に悪魔の輪に落ちてしまいます。 os/unix/ngx_process_cycle.c で ngx_single_process_cycle の定義を直接見つけます。
最初の for ループに次のコードを追加します:
<code><span>for</span> (i = <span>0</span>; ngx_modules[i]; i++) { <span>char</span> * p = NULL; <span>if</span> (ngx_modules[i]->commands != NULL) { p = ngx_modules[i]->commands->name.data; } <span>if</span> (ngx_modules[i]->init_process) { <span>if</span> (ngx_modules[i]->init_process(cycle) == NGX_ERROR) { <span>/* fatal */</span><span>exit</span>(<span>2</span>); } <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s init process\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p); } <span>else</span> { <span>printf</span>(<span>"[ngx_process_cycle] module ctx_index=%d index=%d name=%s\n"</span>, ngx_modules[i]->ctx_index, ngx_modules[i]->index, p); } } <span>printf</span>(<span>"[ngx_process_cycle] for ngx_modules init done\n"</span>);</code>
この機能は、現在 nginx にあるモジュールと関連するインデックスと名前を出力することです。
2 番目の for ループでは、主に ngx_process_events メソッドが使用されています。検索した結果、これはマクロであることがわかり、epoll モジュールをロードしたため、event/modules/ngx_epoll_module にあります。 .c
コードは次で見つかりました:
<code>ngx_event_actions = ngx_epoll_module_ctx.actions;</code>
ngx_process_events メソッドが、実際には ngx_epoll_module_ctx モジュールのアクションの ngx_epoll_process_events メソッドであることがわかりました。このメソッド内で epoll_wait メソッドが呼び出される場所を見つけて、次のコードを追加します:
<code><span>printf</span>(<span>"[ngx_epoll_module] epoll wait\n"</span>); events = epoll_wait(ep, event_list, nevents, timer); <span>printf</span>(<span>"[ngx_epoll_module] epoll wait ---\n"</span>);</code>
実行結果を再作成:
[main] で ngx_single_process_cycle を開始します
[ngx_process_cycle] モジュール ctx_index=0 インデックス=0 名前=デーモン
[ngx_process_cycle] モジュール ctx_index=0 インデックス=1 名前=error_log
[ngx_process_cycle] モジュール ctx_index=0 インデックス=2 名前=インクルード
[ngx_process_cycle] モジュール ctx_index=0 インデックス=3 名前=イベント
[ngx_process_cycle] モジュール ctx_index=0 インデックス=4 名前=接続初期化プロセス
[ngx_process_cycle] モジュール ctx_index=1 インデックス=5 名前=rtsig_signo
[ngx_process_cycle] モジュール ctx_index=2 インデックス=6 名前=epoll_events
[ngx_process_cycle] モジュール ctx_index=0 インデックス=7 名前=http
[ngx_process_cycle] モジュール ctx_index=0 インデックス=8 名前=サーバー
[ngx_process_cycle] モジュール ctx_index=1 インデックス=9 名前=log_format
[ngx_process_cycle] モジュール ctx_index=2 インデックス=10 名前=(null)
[ngx_process_cycle] モジュール ctx_index=3 インデックス=11 名前=インデックス
[ngx_process_cycle] モジュール ctx_index=4 インデックス=12 名前=許可
[ngx_process_cycle] モジュール ctx_index=5 インデックス=13 名前=書き換え
[ngx_process_cycle] モジュール ctx_index=6 インデックス=14 名前=proxy_pass
[ngx_process_cycle] モジュール ctx_index=7 インデックス=15 名前=(null)
[ngx_process_cycle] モジュール ctx_index=8 インデックス=16 名前=(null)
[ngx_process_cycle] モジュール ctx_index=9 インデックス=17 名前=(null)
[ngx_process_cycle] モジュール ctx_index=10 インデックス=18 名前=(null)
[ngx_process_cycle] モジュール ctx_index=11 インデックス=19 名前=gzip
[ngx_process_cycle] モジュール ctx_index=12 インデックス=20 名前=charset_map
[ngx_process_cycle] モジュール ctx_index=13 インデックス=21 名前=ユーザーID
[ngx_process_cycle] モジュール ctx_index=14 インデックス=22 名前=期限切れ
[ngx_process_cycle] モジュール ctx_index=15 インデックス=23 名前=output_buffers
[ngx_process_cycle] モジュール ctx_index=16 インデックス=24 名前=(null)
[ngx_process_cycle] モジュール ctx_index=17 インデックス=25 名前=(null)
ngx_modules の [ngx_process_cycle] の初期化が完了しました
[ngx_epoll_module] epoll お待ちください
^C[ngx_epoll_module] epoll wait —
合計 25 個のモジュールが見つかりました。接続モジュールのみが init_process メソッドを持ち、一部のモジュール名は空です。最後に、プログラムは epoll モジュールに入り、epoll_wait 呼び出しでブロックされます。後続の print ステートメントは、CTRL+C が起動された後にのみ実行されます。
ここでは、nginx のモジュールの定義を詳しく見ることができます。このコードが構造体として定義されている場合、nginx で使用される実際の型はすべて _t で終わることが簡単にわかります。 _s で終わります。nginx_module_s は core/ngx_conf_file.h ファイルで定義されています:
<code><span>struct</span> ngx_module_s { ngx_uint_t ctx_index; ngx_uint_t index; <span>void</span> *ctx; ngx_command_t *commands; ngx_uint_t type; ngx_int_t (*init_module)(ngx_cycle_t *cycle); ngx_int_t (*init_process)(ngx_cycle_t *cycle); <span>#if 0</span> ngx_int_t (*init_thread)(ngx_cycle_t *cycle); <span>#endif</span> };</code>
2 つのインデックス番号と、コマンドと 3 つの関数があります。具体的な意味は後で使用します。
他に 2 つの構造 ngx_event_module_t と ngx_event_actions_t があります。後者は前者のメンバーです。前者は nginx イベント モジュールですが、抽象的であり、特定のプラットフォームでは異なるタイプになります。ここでは epoll です。
ngx_event_module_t は次のとおりです:
<code>typedef struct { ngx_str_t <span>*name</span>; void <span>*(</span><span>*create_conf</span>)(ngx_cycle_t <span>*cycle</span>); char <span>*(</span><span>*init_conf</span>)(ngx_cycle_t <span>*cycle</span>, void <span>*conf</span>); ngx_event_actions_t actions; } ngx_event_module_t;</code>
epoll インスタンスは次のとおりです:
<code>ngx_event_module_t ngx_epoll_module_ctx = { &epoll_name, ngx_epoll_create_conf, <span>/* create configuration */</span> ngx_epoll_init_conf, <span>/* init configuration */</span> { ngx_epoll_add_event, <span>/* add an event */</span> ngx_epoll_del_event, <span>/* delete an event */</span> ngx_epoll_add_event, <span>/* enable an event */</span> ngx_epoll_del_event, <span>/* disable an event */</span> ngx_epoll_add_connection, <span>/* add an connection */</span> ngx_epoll_del_connection, <span>/* delete an connection */</span><span>NULL</span>, <span>/* process the changes */</span> ngx_epoll_process_events, <span>/* process the events */</span> ngx_epoll_init, <span>/* init the events */</span> ngx_epoll_done, <span>/* done the events */</span> } };</code>
たまたま、ngx_event_module_t のアクション メンバーが epoll に関連するいくつかの関数として ngx_epoll_module_ctx で定義されており、前の ngx_process_events が次の 2 行のコードで連結されています。
event/ngx_event.h 内
<code><span>#<span>define</span> ngx_process_events ngx_event_actions.process_events</span></code>
event/modules/ngx_epoll_module.c
<code><span> ngx_event_actions </span>=<span> ngx_epoll_module_ctx.actions;</span></code>
ngx_event_actions は、event/ngx_event.c 内のグローバル変数として定義されています:
<code>ngx_event_actions_t ngx_event_actions;</code>
次に、nginx での epoll の使用を見てみましょう。
続く…
上記では、nginx ソース コード (4) の主要なプロセスをさまざまな側面を含めて紹介していますが、PHP チュートリアルに興味のある友人に役立つことを願っています。