C C 伺服器開發 程序間通訊元件的實現

2021-10-10 06:18:20 字數 3968 閱讀 9286

乙個完整的linux核心一般由五大部分組成,他們分別是記憶體管理,程序管理,程序間通訊,虛擬檔案系統和網路介面。

記憶體管理主要完成的是如何合理有效地管理整個系統的物理記憶體,同時快速響應核心各個子系統對記憶體分配的請求。

linux記憶體管理支援虛擬記憶體,而多餘出的這部分記憶體就是通過磁碟申請得到的,平時系統只把當前執行的程式塊保留在記憶體中,其他程式塊則保留在磁碟中。

在記憶體緊缺時,記憶體管理負責在磁碟和記憶體間交換程式塊。

程序管理主要控制系統程序對cpu的訪問。當需要某個程序執行時,由程序排程器根據基於優先順序的排程演算法啟動新的程序。:linux支援多工執行,那麼如何在乙個單cpu上支援多工呢?這個工作就是由程序排程管理來實現的。在系統執行時,每個程序都會分得一定的時間片,然後程序排程器根據時間片的不同,選擇每個程序依次執行,例如當某個程序的時間片用完後,排程器會選擇乙個新的程序繼續執行。由於切換的時間和頻率都非常的快,由此使用者感覺是多個程式在同時執行,而實際上,cpu在同一時間內只有乙個程序在執行,這一切都是程序排程管理的結果。

程序間通訊主要用於控制不同程序之間在使用者空間的同步、資料共享和交換。由於不用的使用者程序擁有不同的程序空間,因此程序間的通訊要借助於核心的中轉來實現。一般情況下,當乙個程序等待硬體操作完成時,會被掛起。當硬體操作完成,程序被恢復執行,而協調這個過程的就是程序間的通訊機制。

程序間通訊主要用於控制不同程序之間在使用者空間的同步、資料共享和交換。由於不用的使用者程序擁有不同的程序空間,因此程序間的通訊要借助於核心的中轉來實現。一般情況下,當乙個程序等待硬體操作完成時,會被掛起。當硬體操作完成,程序被恢復執行,而協調這個過程的就是程序間的通訊機制。

(1)程序間通訊的目的

(2)程序間通訊方式

程序間通訊主要分為兩大標準:system v 標準和 posix 標準。

關於system v標準的程序間通訊主要有以下幾類:

1. 管道

管道適用於程序間的資料傳輸。本質上管道是作業系統在核心中為程序開闢了一塊緩衝區,多個程序通過訪問同一緩衝區進行通訊,資料在緩衝區中以讀寫的方式被不同程序獲取和操作。

管道有三大特性:

管道主要分為匿名管道和命名管道:

匿名管道

前面說了管道是作業系統為程序在核心中分配的一塊緩衝區,匿名管道就是指這塊緩衝區沒有識別符號,因此其他程序無法直接訪問匿名管道,只有類似父子程序這樣的具有親緣關係的程序才能使用匿名管道進行通訊(原因是子程序會複製父程序的pcb,其中包括這塊資訊)。匿名管道的建立使用如下介面:

int pipe(int fd[2])

這個介面的作用是建立乙個匿名管道,並向使用者返回這個管道的操作控制代碼,其中引數fd[2]中fd[0]用於從管道中讀取資料,fd[1]用於從管道中寫入資料,如果建立成功返回 0, 建立失敗返回 -1.

匿名管道的特性是:

這些特性體現了管道自帶同步與互斥。

命名管道

命名管道和匿名管道相反,命名管道是有識別符號的一塊緩衝區,並且這個識別符號一般是乙個可見於檔案系統的檔案。所以命名管道是乙個特殊型別的檔案,其他程序可以通過這個識別符號找到這塊緩衝區,即通過開啟同乙個管道檔案,訪問到同一緩衝區,進而實現程序間通訊。

建立乙個命名管道既可以使用mkfifo filename命令也可以使用介面,函式介面如下:

int mkfifo(const char* pathname, mode_t mode)

引數pathname是命名管道檔案的名稱,mode是檔案許可權 。如果建立成功返回0,失敗返回-1.

命名管道的開啟特性:

不管是匿名還是命名管道,同查那個對管道進行的資料操作的大小不超過pipe_buf這個巨集的大小,預設是4kb。

2.共享記憶體

共享記憶體用於程序間的資料共享,是最快的程序間通訊。共享記憶體的建立大概是以下步驟:首先,在物理記憶體中開闢一塊空間,將這塊物理記憶體對映到程式的虛擬位址空間,程序就可以通過虛擬位址來訪問這塊記憶體。多個程序對映到同一物理記憶體,這樣進行通訊的方式,不需要進入核心,只需要再共享的記憶體區進行操作即可。其他方式的通訊都是因為核心中的緩衝區,程序在通訊的時候會涉及核心態和使用者態的兩次資料拷貝。而共享記憶體不會所以速度更快。

共享記憶體的操作流程:

int

shmget

(key_t

key,

intsize

,int

flag)/

/建立乙個共享記憶體

void

*shmat

(int

shmid

,void

*addr

,int

flag)/

/建立對映

intshmdt

(void

*shmstart)/

/解除對映

intshmctl

(int

shmid

,int

cmd,

struct

shmid_ds*bf

)//操作共享記憶體//

cmd引數為ic_rmid的時候是刪除共享記憶體0,

表示這塊共享記憶體不會再接收對映鏈結,當這塊共享記憶體的對映鏈結為

0的時候,則自動釋放。需要注意的是共享記憶體自帶沒有同步與互斥。

3. 訊息佇列訊息佇列用於程序間的資料傳輸(有識別符號)

訊息佇列實際上就是核心中的乙個優先順序佇列,多個程序通過向同乙個佇列中 新增 或者 獲取 節點來實現通訊。主要是傳輸乙個有型別(優先順序)的資料塊。

特性:

訊號量

訊號量用於實現程序間的控制,主要是同步和互斥。

本質:核心中的乙個計數器(對資源進行計數) + pcb等待佇列

互斥的實現:通過只有 0 / 1 的計數器,實現對臨界資源訪問狀態的標記,在訪問臨界資源

之前先獲取訊號量,計數 -1;若計數 <0 則使程序等待(將程序pcb加入佇列中);否則可

以對臨界資源進行訪問(並且在訪問期間,已經將臨界資源的狀態置為不可訪問狀態,因此

可一保證其他程序不會再訪問臨界資源。當前程序訪問完畢之後,則對計數進行+1,則喚醒

乙個程序(將乙個pcb出隊,置為執行狀態)

同步的實現:訊號量是乙個對資源的計數,可以通過計數判斷是否能夠獲取乙個資源進行處

理;若計數小於 0,則表示不能獲取(並且對計數進行 -1),需要等待(加入pcb佇列)。

這時候若其他程序生產乙個資源,則會對計數進行 +1,若計數 <= 0 ,則喚醒乙個程序。

(負數表示正在等待程序的數量,如果為正說明沒有程序需要資源)。

linux核心中的虛擬檔案系統用乙個通用的檔案模型表示了各種不同的檔案系統,這個檔案模型遮蔽了很多具體檔案系統的差異,使linux核心支援很多不同的檔案系統,這個檔案系統可以分為邏輯檔案系統和裝置驅動程式:邏輯檔案系統指linux所支援的檔案系統,例如ext2、ext3和fat等;裝置驅動程式指為每一種硬體控制器所編寫的裝置驅動程式模組。

網路介面提供了對各種網路標準的實現和各種網路硬體的支援。網路介面一般分為網路協議和網路驅動程式。網路協議部分負責實現每一種可能的網路傳輸協議。網路裝置驅動程式則主要負責與硬體裝置進行通訊,每一種可能的網路硬體裝置都有相應的裝置驅動程式。

本群免費分享學習資料(c/c++,linux,golang,nginx,zeromq,mysql,redis,fastdfs,mongodb,zk,流**,cdn,p2p,k8s,docker,ffmpeg,tcp/ip,協程,dpdk,嵌入式)等。

交流討論領取資料**群q:1106675687

程序間通訊之客戶程序 伺服器程序屬性

下面詳細說明客戶程序和伺服器程序的某些屬性,這些屬性受到它們之間所使用的ipc型別的影響。最簡單的關係型別是使客戶呼叫fork然後呼叫exec執行所希望的伺服器程序。在fork之前先建立兩個半雙工管道使資料可在兩個方向傳輸。中的圖15 8是這種形式的乙個例子。被執行的伺服器程式可能是設定使用者id的...

Linux 開發 程序間通訊 訊息佇列學習筆記

訊息佇列讀完結點就被刪除 步驟總結 msgget 在核心中建立訊息佇列 鏈式佇列 mmgctl 刪除 訊息佇列 修改核心空間屬性 mmgsnd 使用者空間資料寫入訊息佇列 mmgrcv 使用者空間可以讀取到核心空間的訊息佇列 阻塞方式 非阻塞方式 a b 無親緣關係的兩個程序 通過訊息佇列進行通訊 ...

元件與伺服器通訊

1.元件掛載階段通訊 在元件掛在前請求資料 時間上來說會比componentdidmount早一些,越早執行就越快返回元件,但時間幾乎微乎其微可以忽略不計 componentwillmount 複製 2.在元件掛載完成後請求 官方規範 這個階段是元件通訊的最佳時期 1 組價在這個階段已經處於掛載狀態...