Nginx原始碼分析 程序管理之worker程序

2022-07-16 20:21:10 字數 3010 閱讀 6081

**

本文著手分析一下worker程序的情況。首先找到worker程序的入口地方——ngx_worker_process_cycle。這個函式不光是worker程序的入口函式,同時也是worker程序迴圈工作的主體函式,看函式名含有乙個cycle嘛。進入這個cycle函式,第一件事就是呼叫ngx_worker_process_init(cycle, 1);對worker程序進行初始化操作。先看看這個worker程序的初始化過程。

[cpp]view plain

copy

print

?ngx_process = ngx_process_worker;  

if(ngx_set_environment(cycle, null) == null)   

進入初始化就將全域性變數ngx_process設定為worker程序的標誌,由於這個變數是從master程序複製過來的,所以沒設定前就是master程序的標誌。然後設定相應的環境變數。接下去就是設定了一些列的資源限制,id等玩意,這裡就忽略**了。

[cpp]view plain

copy

print

?for

(i = 0; ngx_modules[i]; i++)   

}  }  

此處迴圈呼叫每個模組的init_process,完成每個模組自定義的程序初始化操作,一般在模組定義的時候設定這個**指標的值,即註冊乙個函式給它。做模組開發的時候,貌似使用得挺少的,遇到的時候好好關注下。

[cpp]view plain

copy

print?/*

此處迴圈用於關閉其他worker程序的無用channel資源

*/for

(n = 0; n < ngx_last_process; n++)   

/*全域性變數ngx_process_slot的值是建立worker程序的時候,從

master程序複製過來的,所以此處ngx_process_slot就指本worker

程序在ngx_process_slot陣列中的索引位置。此處不處理本worker

程序,所以跳過。

*/if

(n == ngx_process_slot)   

/*channel不存在,繼續跳過。

*/if

(ngx_processes[n].channel[1] == -1)   

/*ngx_processes陣列中儲存的是每個worker程序的資源,是master程序負責建立的。

因此建立乙個worker程序的時候,就一同將這些資源複製過來了,所以此處就關閉

無用的channel——其他worker程序的讀端檔案描述符,保留寫端檔案描述符做

worker間的通訊之用。

*/if

(close(ngx_processes[n].channel[1]) == -1)   

}  /*

關閉本worker程序channel的寫端檔案描述符,因為每個worker程序只從自己的channel

上讀,而不會寫。寫自己channel的是master和其他worker程序。這也是上面為什麼要

關閉其他worker程序channel的讀端。

*/if

(close(ngx_processes[ngx_process_slot].channel[0]) == -1)   

針對這段**採用直接注釋**的方式進行分析,感覺挺自然的,還不錯,以後碰到比較長的**段都採用這種方式進行了。

[cpp]view plain

copy

print?if

(ngx_add_channel_event(cycle, ngx_channel, ngx_read_event,  

ngx_channel_handler)  

== ngx_error)  

ngx_channel就是worker程序channel的讀端,這裡呼叫ngx_add_channel_event將channel放入nginx關心的集合中,同時關注起這個channel上的讀事件,也即這個channel上有資料到來後,就立馬採取讀channel操作。此處的新增乙個channel的讀事件是worker程序初始化的關鍵之處。到此,初始化過程就結束了,回到worker迴圈主體看看吧。

[cpp]view plain

copy

print

?for

( ;; )   

}  /*

處理完所有事件後,呼叫ngx_worker_process_exit函式,worker程序退出。

*/if

(ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)  

}  ngx_log_debug0(ngx_log_debug_event, cycle->log, 0, 

"worker cycle"

);  

/*這裡是worker程序處理事件的核心開始。也即是,worker程序從裡開始做一些特定的事情了,

我們完全可以修改此處的**,讓nginx為我們做一些其他的事情,呵呵。

*/ngx_process_events_and_timers(cycle);  

/*worker程序收到了sigint訊號,退出。

*/if

(ngx_terminate)   

/*worker程序收到了sigquit訊號,如果此時worker程序不是出於exiting狀態,

就將設定ngx_exiting為1,讓其進入exiting狀態;同時關閉監聽套介面。

*/if

(ngx_quit)   

}  /*

worker程序收到了sigusr1訊號

*/if

(ngx_reopen)   

}  通過上述分析發現worker程序的cycle比master簡單不少啊,到此,worker程序的大體框架就差不多了。

Nginx原始碼分析之ngx array t

ngx array t是乙個順序容器,類似於stl中的vector可以動態擴容。原始碼位置 nginx src core ngx array.h nginx src core ngx array.c typedef struct ngx array s ngx array t struct ngx ...

nginx原始碼分析之ngx list

ngx list t是nginx封裝鍊錶的容器,其原始碼位於 宣告 nginx src core ngx list.h 定義 nginx src core ngx list.c 在nginx中使用頻繁,例如http頭部就是用ngx list t儲存的。nginx的鍊錶 頭 結構為ngx list t...

nginx 原始碼分析

近期準備研究一下nginx原始碼,此處記錄一下。計畫 1 了解evan miller 的文章 2 了解nginx的組織架構 3 了解nginx的基本資料結構 4 熟悉nginx的主要module及執行機制,主要是core http event os 5 簡單的module開發及測試 一 準備 為了方...