これまでの学習ノートを読んだ後、nginx の起動プロセスをある程度理解できたと思います。このセクションからは、各モジュールを深く掘り下げて、各モジュール内の主な操作を学びたいと思います。
この記事の引用元: http://blog.csdn.net/lengzijian/article/details/7598996
今日は、前回の起動で、各モジュールを多数呼び出すことについて説明しました。
のフック関数 このメソッドは主に ngx_event_conf_t 構造体を作成し、メモリ空間を割り当てます。
たとえば、読み取られたファイルには次の行があります:
[cpp] view
普通のコピープリント?
イベント
{
epoll を使用します
- }
- この場所でのイベントはブロック命令です。命令は括弧内で設定できます。これらの命令は src/event/ngx_event.c
- [cpp] ビューで定義されています。 普通のコピープリント?
- static ngx_command_t ngx_event_core_commands[] = {
{ ngx_string(
"worker_connections"
) 、- NGX_EVENT_CONF|NGX_CONF_TAKE1、 ngx_event_connections ,
- 0,
- 0, NULL },
- ...(ここでは省略)
- { ngx_string( 「接続」
- ),
- NGX_EVENT_CONF|NGX_CONF_TAKE1、
- ngx_event_connections、
- 0、
- 0、 NULL }、
- {ngx_string( "使用"
- ) )、
- NGX_EVENT_CONF|NGX_CONF_TAKE1、
- ngx_event_use、
- 0、
- 0、 NULL }、
- ngx_null_command
- };
- イベントが解析されると、次の関数がコールバックされます:
- [cpp] view 普通のコピープリント?
- src/event/ngx_event.c
- static char *
- ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
- {
- char *rv;
- void ***ctx;
- ngx_uint_t i;
- ngx_conf_t pcf;
- ngx_event_module_t *m;
- /* イベントモジュールの数を数え、インデックスを設定します */
- //计算event模块数,并そして记录
- ngx_event_max_module = 0;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- 続けます;
- }
- ngx_modules[i]->ctx_index = ngx_event_max_module++;
- }
- ctx = ngx_pcalloc(cf->pool, sizeof(void *));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
- //のために每一イベント模块割り当て空間、保存用响应配置结构的地址
- //共割了ngx_event_max_module个空间
- *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));
- if (*ctx == NULL) {
- return NGX_CONF_ERROR;
- }
- *(void **) conf = ctx;
- for (i = 0; ngx_modules[i]; i++) {
- if (ngx_modules[i]->type != NGX_EVENT_MODULE) {
- 続きます;
- }
- m = ngx_modules[i]->ctx;
- if
- (m->create_conf) { (*ctx)[ngx_modules[i]->ctx_index] = m->create_conf(cf->cycle);
- ((*ctx)[ngx_modules[i]->ctx_index] == NULL) {
- pcf = *cf->ctx = ctx; cf->module_type = NGX_EVENT_MODULE
- cf-> ;cmd_type = NGX_EVENT_CONF;
- //イベントはブロック命令であるため、他の多くの命令をイベント ドメインで構成できます。 、ここでイベント ブロック内の命令の解析を開始し、初期化作業を完了します。
- rv = ngx_conf_parse(cf, NULL);
- *cf = pcf; if (rv != NGX_CONF_OK)
- if
- (ngx_modules [i] - > type!= ngx_event_module){
- m= ngx_modules [ i] - > ctx;//各イベントを実行するModuleのinit_conf関数は、「 ' to ' to use ' to ' to ' t d to d. t;init_conf(cf->cycle, (*ctx) [ngx_modules[i]->ctx_index]);
- }
- }
ngx_events_block() 関数の最も重要なプロセスは、ngx_conf_parse(cf, NULL) を呼び出すことです。ここで ngx_conf_parse() を呼び出す関数は、設定ファイル内の events ブロックの解析を完了し、それによってすべてのイベントを呼び出します。命令のコールバック関数により、構成ファイルの解析の初期化が完了します。しかし、ここで個人的な質問がありますので、先輩方に質問した後、質問と回答を明記します******。
2. confの初期化(init_conf)
ngx_event_init_conf()
このメソッドは主にngx_event_conf_t構造体を初期化します。
3.ngx_event_module_init
名前からするとモジュールの初期化操作ですが、各モジュールのソースコードを見るとinitコールバック関数を持たないモジュールが多いことが分かります。私も、すべてのコードを学習した後に答えを見つけたいと思っているので、なぜここにあるのか悩んでいます。
[cpp]ビュー 普通のコピープリント?
- src/event/ngx_event.c
- static ngx_int_t
- ngx_event_module_init(ngx_cycle_t *cycle)
- {
- void ***cf;
- u_char *共有;
- size_t サイズ、cl;
- ngx_shm_t shm;
- ngx_time_t *tp;
- ngx_core_conf_t *ccf;
- ngx_event_conf_t *ecf;
- // 判断ngx_events_module かどうか调用过初期化conf操作
- cf = ngx_get_conf(cycle-> conf_ctx、ngx_events_module);
- if (cf == NULL) {
- ngx_log_error(NGX_LOG_EMERG, cycle->log, 0、
- 「設定に「イベント」セクションがありません」 );
- return NGX_ERROR;
- }
- //获取ngx_event_core_module模块の構成结构
- ecf = (*cf)[ngx_event_core_module.ctx_index];
- //イベント内のモジュールであるかどうかを確認します。たとえば、使用します。。。。
- if (!ngx_test_config && ngx_process
- ngx_log_error(NGX _LOG_NOTICE, サイクル->ログ, 0 ,
- 「イベントメソッド」 , ecf->name);
- }
- //ngx_core_module モジュールの構成構造を取得します ccf = (ngx_core_conf_t *) ngx_ get_conf(cycle- >conf_ctx, ngx_core_module);
- // ngx_core_module モジュールの構成構造体から timer_resolution パラメータを取得します ngx_timer_resolution = ccf->timer_resolution;
- #if !(NGX_WIN32)
- {
- ngx_int_t 制限
- rlimit rlmt; //現在のプロセスの能力を取得します 開いているファイルの最大数 man getrlimit
- (getrlimit(rlimit_nofile、&rlmt)== -1){
- ngx_log_error(ngx_log_alert、cycle-> log、ngx_errno、else{
- _モジュールへの最大接続数は無制限です
- / / または ngx_event_core_module 接続が ngx_core_module の最大接続数より大きいです
- (ECF-& GT; 接続 & GT; (ngx_uint_t) rlmt.rlim_cur
- (ccf-& gt; _NOFILE == ngx_conf_unset) limit = (ccf ->rlimit_nofile == NGX_CONF_UNSET) ?
- (ngx_int_t) rlmt.rlim_cur: ccf- & gt;
- " オープンファイルのリソース制限: %i" ); (NGX_WIN32) */
- //マスタープロセスが閉じている場合は、 return
- //マスタープロセスを閉じることは単一プロセスの作業メソッドを意味するため、
- //後続の操作では、ロックやその他の作業を実装するための共有メモリが作成されますが、これは単一プロセスには必要ありません。
- if (ccf->master == 0) {
- NGX_OK }
- // 受け入れミューテックスの場合すでに存在するため、再度作成する必要はありません。
- } /* cl はキャッシュ以上である必要がありますline size */
- cl = 128; // ここでサイズを作成します。この共有メモリは 3 つの等しいセグメントに分割されます
- サイズ= cl + cl ,
- shm.size = サイズ shm.name.len = sizeof (
- 「nginx_shared_zone」 ); shm.name.data = (u_char *)
- "nginx_share d_zone";
- shm.log = サイクル->log
- (ngx_shm_alloc(&s)うーん) = NGX_OK ) {
- NGX_ERROR;
- ; .addr;
- //ミューテックスの取得を受け入れる共有メモリの最初の cl サイズメモリ
- ngx_accept_mutex_ptr = (ngx_atomic_t *) 共有メモリ
- ngx_accept_mutex.spin = (ngx_uint_t) -1; /* 受け入れミューテックスを作成します
- 受け入れミューテックスの実装は、アトミック操作をサポートするかどうか、および対応するアトミック操作があるかどうかによって異なります。 ; それ以外の場合は、受け入れミューテックスを実装するためにファイル ロックが使用されます。
- accept mutex の機能は、パニック グループを回避し、ワーカー プロセスの負荷分散を実現することです。
- */ngx_accept_mutex、共有、cycle-> lock_file.data)
- != ngx_ok) //メモリの 2 番目のセグメントの cl サイズのアドレスを取得します
- ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl)
- (void ); ngx_atomic_cmp_set (ngx_connection_counter, 0, 1);
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, サイクル - >log, 0,
- x_connection_counter);
- //メモリ cl アドレスの 3 番目のセグメントのサイズを取得します。
- ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl)
- tp = ngx_timeofday() ;
- ngx_random_number = (tp-> ; msec
- returnNGX_OK; 前述したように分析では、ワーカー プロセスが作成されると、ワーカー プロセスは最初にプロセスを初期化し、この時点で ngx_event_process_init 関数が呼び出されます。
- [cpp]ビュー 普通のコピープリント?
- src/event/ngx_event.c
- staticngx_int_t
- ngx_event_process_init(ngx_cycle_t *cycle)
- {
- ngx_uint_t m、私; ngx_event_t *rev、*wev;
- ngx_listening_t *ls;
- ngx_connection_t *c、*next、*old
- ; ngx_event_conf_t *ecf;
- ngx_event_module_t *module;
- //前と同様に、応答モジュールの構成構造を取得します
- ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx _コア_モジュール);
- ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module);
- //マスタープロセスがオープン、ワーカープロセスが1より大きい、accept_mutexが作成されました
- //cai accept mutex を開きます
- if
- (ccf->master &&ccf->worker_processes > 1 &&ecf->accept_mutex) { ngx_use_accept_mutex = 1; / /ミューテックスを使用する
- ngx_accept_mutex_held = 0; //受け入れミューテックスを取得するかどうか
- ngx_accept_mutex_lay = ecf->accept_mutex_lay; //ミューテックスの競合に失敗した後、待機中次のスクランブル時間間隔用
- } else {
- ngx_use_accept_mutex = 0 ; }
- #if (NGX_THREADS )
- //スレッドはさておき
- #endif
- // カウンターを初期化する、ここに赤が作成されます Black Tree、タイマー、後で詳しく説明します
- if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
- return NGX_ERROR;
- }
- for (m = 0; ngx_modules[m]; m++) {
- //前にここで述べたように、非 NGX_EVENT_MODULE モジュールをスキップします
- }
- // 使用しない構成命令で指定されたモジュールはスキップされます。Linux のデフォルトの epoll です。 ->use) { module = ngx_modules[m]->ctx; /*init を呼び出します特定の時間モジュールの関数
- (これらのモジュールは src/event/modules ディレクトリにあります)。したがって、nginx の時間モジュールに抽象化のレイヤーが作成されており、これにより、さまざまなシステムがさまざまなイベント モデルを使用しやすくなり、新しい時間モデルを拡張します。私たちは epoll に重点を置く必要があります。
- は、実際には ngx_epoll_init 関数を呼び出しています。 module->actions 構造は、epoll のすべてのインターフェイス関数をカプセル化します。 nginx は、アクション構造を通じて epoll をイベント抽象化レイヤーに登録します。
- アクションのタイプは、src/event/ngx_event.h にある ngx_event_action_t です
- これらの具体的な内容については、次のセクションで説明します。
- module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
- *faタル */ exit(2)
- Break;
- }
- //内容の一部
- //すべての接続を保存するグローバル ngx_connection_t 配列を作成します
- //この処理は各ワーカープロセスで実行されるため、各ワーカーは独自の接続配列を持ちます
- cycle->connections =
- ngx_alloc(sizeof(ngx_connection_t) *cycle->connection_n 、サイクル>ログ);
- if (サイクル>接続 == NULL) {
- c = サイクル>接続; 创/ // 読み取り値のグループを作成します。
- if
- (cycle->read_events == NULL) { }
- rev =cycle->read_events;
- for (i = 0; i
connection_n; i++) { - rev[i].closed = 1 ;
- [i].instance = 1;
- #if (NGX_THREADS)
- rev[i].lock = &c[i].lock
- rev[ i].own_lock = &c[i].lock #endif
- }
- //创建一写イベント数组
- cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle-& gt;connection_n、
- cycle->ログ);
- if (cycle->write_events == NULL) {
- return NGX_ERROR;
- }
- wev = cycle->write_events;
- for (i = 0; i connection_n; i++) {
- wev[i].closed = 1;
- #if (NGX_THREADS)
- wev[i].lock = &c[i].lock;
- wev[i].own_lock = &c[i].lock;
- #endif
- }
- i = cycle->connection_n;
- 次 = NULL;
- //初化整个接続数组
- do {
- i--;
- c[i].data = 次;
- c[i].read = &cycle->read_events[i];
- c[i].write = &cycle->write_events[i];
- c[i].fd = (ngx_socket_t) -1;
- next = &c[i];
- #if (NGX_THREADS)
- c[i].lock = 0;
- #endif
- } (i);
- サイクル->free_connection_n = サイクル->
- /* 各リスニング ソケット用 */
- //各リスニング ソケットの接続配列から接続、つまりスロット ls =cycle->listening を割り当てます。 els; solt
- に接続します c = ngx_get_connection(ls[i].fd,cycle->log)
- (c == NULL) {
- NGX_エラー }
- c->log = &ls[i].log;
- c->listening = &ls[i];
- ls[i].connection = c;
- rev = c->read;
- rev->log = c->log;
- rev->accept = 1; //读時間间発行,调用accept
- #if (NGX_HAVE_DEFERRED_ACCEPT)
- //省略
- #endif
- if (!(ngx_event_flags & NGX_USE_IOCP_EVENT)) {
- if (ls[i].previous) {
- /*
- * バインドされていた古い accept イベントを削除します
- * 古い サイクル 読み取り イベント 配列
- */
- old = ls[i].previous->connection;
- if (ngx_del_event(old->read, NGX_READ_EVENT, NGX_CLOSE_EVENT)
- == NGX_ERROR)
- {
- return NGX _エラー;
- }
- old->fd = (ngx_socket_t) -1;
- }
- }
- //コールバック関数を登録します ngx_event_accept
- rev->handler = ngx_even t_accept;
- 当面はリスニングソケットを epoll に置かないでください。しかし、
- {{
- }}} eLSe
- {
- //使用した後、このリスニングソケットを epoll に置きます。 ️ #endif
- }
- return NGX_OK
- }
- ここまでで、イベント駆動型の初期化が完了しました。 以上、nginx ソースコード学習メモ (20) - イベント モジュール 1 - 初期化 (IOC とカウンターの内容を含む) を紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。

PHPは、特にWeb開発の分野で、最新のプログラミングで強力で広く使用されているツールのままです。 1)PHPは使いやすく、データベースとシームレスに統合されており、多くの開発者にとって最初の選択肢です。 2)動的コンテンツ生成とオブジェクト指向プログラミングをサポートし、Webサイトを迅速に作成および保守するのに適しています。 3)PHPのパフォーマンスは、データベースクエリをキャッシュおよび最適化することで改善でき、その広範なコミュニティと豊富なエコシステムにより、今日のテクノロジースタックでは依然として重要になります。

PHPでは、弱い参照クラスを通じて弱い参照が実装され、ガベージコレクターがオブジェクトの回収を妨げません。弱い参照は、キャッシュシステムやイベントリスナーなどのシナリオに適しています。オブジェクトの生存を保証することはできず、ごみ収集が遅れる可能性があることに注意する必要があります。

\ _ \ _ Invokeメソッドを使用すると、オブジェクトを関数のように呼び出すことができます。 1。オブジェクトを呼び出すことができるように\ _ \ _呼び出しメソッドを定義します。 2。$ obj(...)構文を使用すると、PHPは\ _ \ _ Invokeメソッドを実行します。 3。ロギングや計算機、コードの柔軟性の向上、読みやすさなどのシナリオに適しています。

繊維はPhp8.1で導入され、同時処理機能が改善されました。 1)繊維は、コルーチンと同様の軽量の並行性モデルです。 2)開発者がタスクの実行フローを手動で制御できるようにし、I/O集約型タスクの処理に適しています。 3)繊維を使用すると、より効率的で応答性の高いコードを書き込むことができます。

PHPコミュニティは、開発者の成長を支援するための豊富なリソースとサポートを提供します。 1)リソースには、公式のドキュメント、チュートリアル、ブログ、LaravelやSymfonyなどのオープンソースプロジェクトが含まれます。 2)StackOverFlow、Reddit、およびSlackチャネルを通じてサポートを取得できます。 3)開発動向は、RFCに従うことで学ぶことができます。 4)コミュニティへの統合は、積極的な参加、コード共有への貢献、および学習共有への貢献を通じて達成できます。

PHP and Python each have their own advantages, and the choice should be based on project requirements. 1.PHPは、シンプルな構文と高い実行効率を備えたWeb開発に適しています。 2。Pythonは、簡潔な構文とリッチライブラリを備えたデータサイエンスと機械学習に適しています。

PHPは死にかけていませんが、常に適応して進化しています。 1)PHPは、1994年以来、新しいテクノロジーの傾向に適応するために複数のバージョンの反復を受けています。 2)現在、電子商取引、コンテンツ管理システム、その他の分野で広く使用されています。 3)PHP8は、パフォーマンスと近代化を改善するために、JITコンパイラおよびその他の機能を導入します。 4)Opcacheを使用してPSR-12標準に従って、パフォーマンスとコードの品質を最適化します。

PHPの将来は、新しいテクノロジーの傾向に適応し、革新的な機能を導入することで達成されます。1)クラウドコンピューティング、コンテナ化、マイクロサービスアーキテクチャに適応し、DockerとKubernetesをサポートします。 2)パフォーマンスとデータ処理の効率を改善するために、JITコンパイラと列挙タイプを導入します。 3)パフォーマンスを継続的に最適化し、ベストプラクティスを促進します。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

WebStorm Mac版
便利なJavaScript開発ツール

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

メモ帳++7.3.1
使いやすく無料のコードエディター
