nginx原始碼分析 程序間通訊機制 同步機制

2021-06-27 03:54:43 字數 1769 閱讀 4830

nginx原始碼分析—程序間通訊機制

從nginx的程序模型可以知道,master程序和worker程序需要通訊,nginx中通訊的方式有套接字、共享記憶體、訊號。對於master程序,從外部接受訊號,master程序主要就是監控、接受外部訊號,將有必要的訊號傳遞給worker程序,master程序大部分時間都是阻塞在sigsuspend()函式呼叫上。worker程序遮蔽了所有的外部訊號,那麼master程序就通過套接字和worker程序通訊,worker程序修改全域性變數,使得worker程序接受到了master程序的命令(程序間的套接字被epoll監控)。

共享記憶體是存放父子程序中都需要的全域性變數,比如當前系統接受到的連線,正在處理的連線數目等。

既然使用了共享記憶體,那麼就需要考慮同步,nginx中的同步使用了原子操作、檔案鎖、訊號量(這裡訊號量的值為1,也就是相當於乙個互斥鎖)。雖說實現了這三種,但是對外都是使用了ngx_shmtx_t變數,這個變數成為乙個互斥鎖,使用上述三種同步方式實現了一種對外的互斥鎖,接下來看看實現方式:

首先宣告一點,在nginx中都是非阻塞的,所以在獲取鎖的時候也希望是非阻塞的

對於共享記憶體,使用shmgt &mmap(可以實現檔案到記憶體的對映,也可以不使用檔案的方式來實現對映)來實現,共享記憶體中存放的變數有已經建立成功的tcp連線數、已經處理過的tcp連線數等共6類,共享記憶體的初始化在main中實現,共享記憶體中資料的初始化在ngx_event_module_init函式中實現

上述幾種鎖的屬性設計到阻塞&非阻塞 導致睡眠&不導致睡眠,至於阻塞和非阻塞就是看能否馬上得到呼叫的結果,根據前提條件選擇不同的鎖,比如這裡用原子操作實現的自旋鎖就是阻塞鎖。就是如果沒有獲取鎖,那麼就連續不斷的嘗試一段時間,如果是想占有乙個被短時間占用的資源的話,可以使用這種阻塞鎖,,如果占用的時間過長,不適合使用阻塞鎖,會占用過多的cpu資源。睡眠鎖就是在獲取鎖不成功會導致程序睡眠,缺點是一旦睡眠需要另乙個程序來喚醒,邏輯複雜同時cpu的切換消耗時間。

使用者可以從鎖的使用時間長短角度來選擇使用哪一種鎖,當鎖的使用時間很短,可使用自旋鎖,如果鎖使用時間長,使用睡眠鎖。阻塞鎖就是在一段時間上不停的獲取鎖直到鎖獲取成功。

訊號量和檔案鎖都是睡眠鎖,訊號量使用的sem_wait,檔案鎖使用fcntl(),不過在死啊用的時候要麼成功,要麼睡眠。

訊號量sem_init可以用於執行緒間也可以用於程序間,實現互斥鎖的方法:訊號量為0,嗲用sem_post加1,不會有阻塞,呼叫sem_wait將訊號量間1,如果訊號量不大於0,就阻塞當前程序(程序進入睡眠),直到其他程序將訊號量的值為正數後,這時才能繼續通過訊號量減1而使得當前程序繼續進行。sem_post解鎖,sem_wait實現加鎖。

對於穩健鎖,ngx_trylock_fd實現不會阻塞,不會使得程序睡眠的互斥鎖,ngx_lock_fd提供的互斥鎖在鎖已經被的程序拿到時將會導致當前程序進入睡眠狀態。

基於原子操作,訊號量檔案鎖,ngxin封裝了乙個互斥鎖。

原子變數鎖優先順序高於檔案鎖。

如果不支援原子操作,會使用檔案鎖實現ngx_shmtx_t互斥鎖,使用檔案鎖來提供阻塞、非阻塞的互斥鎖。

支援原子操作卻不支援訊號量

支援原子操作的同時,作業系統也支援訊號量

後兩種的區別在於,支援訊號量只會影響程序ngx_shmtx_lock方法持有鎖的方式,不支援訊號量時,和自旋鎖一樣,支援訊號量,自旋鎖在阻塞一段時間後沒有獲取鎖,那麼訊號量導致程序進入睡眠狀態,只有等到別的程序釋放這個鎖才會被啟用

在不使用訊號量時,nginx互斥鎖和自旋鎖相似,而在使用訊號量後將會使用可能讓程序進入睡眠,不建議使用帶訊號量的ngx_shmtx_lock取鎖方法。

其實做了這麼多的封裝也是為了系統可移植

nginx原始碼學習(五)程序間的通訊

nginx啟動worker程序的函式主體還是比較簡單的 static void ngx start worker processes ngx cycle t cycle,ngx int t n,ngx int t type for迴圈啟動配置的worker程序個數,下面主要分析兩個函式 ngx sp...

ucos II 任務間通訊原始碼分析

ucos ii 2.0版本的任務間通訊提供訊息郵箱和訊息佇列兩種機制,都基於核心的事件控制塊機制實現。訊息郵箱 訊息郵箱主要函式分析 訊息佇列 訊息佇列全域性變數 typedef struct os q os q typedef struct os q data os ext os q osqfre...

nginx 原始碼分析

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