ホームページ  >  記事  >  バックエンド開発  >  nginxのソースコード (4) メインプロセス

nginxのソースコード (4) メインプロセス

WBOY
WBOYオリジナル
2016-08-08 09:27:59862ブラウズ

上記の続きです。

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 チュートリアルに興味のある友人に役立つことを願っています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。