unix程序通訊

2021-06-21 17:10:14 字數 2476 閱讀 4306

管道和fifo(命名管道)

最適合在程序之間實現生產者/消費者的互動。有些程序向管道寫入資料,而另外一些程序則從管道中讀出資料。

訊號量

訊息佇列

允許程序在預定義的訊息佇列中讀和寫訊息來交換訊息(小塊資料)。linux核心提供兩種不同訊息版本:system v ipc和posix訊息。

共享記憶體區

允許程序通過共享記憶體塊來交換資訊。在必須共享大量資料的應用中,這可能是最高效的通訊方式。

套接字

允許不同計算機上的程序通過網路交換資料。套接字還可以用作相同主機上的程序之間的通訊工具;例如,x window系統圖形介面就是使用套接字來允許客戶端和x伺服器交換資料的。

管道是程序之間的乙個單向資料流:乙個程序寫入管道的所有資料都由核心定向到另乙個程序,另乙個程序由此就可以從管道中讀取資料。

在unix的命令shell中,可以使用「|」操作符來建立管道。

eg:$ls | more 第乙個程序(執行ls程式)的標準輸出被重定向到滾到中;第二個程序(執行more程式)從這個管道中讀取輸入。

管道被看做是開啟的檔案,但在已安裝的檔案系統中沒有相應的映像。可以使用pipe()系統呼叫來建立乙個新管道,這個系統呼叫返回一對檔案描述符;然後程序通過fork()把這兩個描述符傳遞給它的子程序,由此與子程序共享管道。程序可以在read()系統呼叫中使用第乙個檔案描述符從管道中讀取資料,同樣也可以在write()系統呼叫中使用第二個檔案描述符向管道中寫入資料。

posix之定義了半雙工管道,因此即使pipe()系統呼叫返回兩個描述符,每個程序在使用乙個檔案描述符之前仍得把另乙個檔案描述符關閉。如果所需要的是雙向資料流,那麼程序必須通過兩次呼叫pipe()來使用兩個不通管道。linux每個管道檔案描述符仍然都是單向的,但那時在使用乙個描述符之前不必把另乙個描述符關閉。

雖然管道是一種十分簡單、靈活、有效的通訊機制,但它們有乙個主要特點,也就是無法開啟已經存在的管道。這就使得任意兩個程序不可能共享同乙個管道,除非管道由乙個共同的祖先程序建立。

為了突破這種限制,unix系統引入了一種稱為命名管道(nemed pipe)或者fifo的特殊檔案型別。fifo非常類似於管道:在檔案系統中不擁有磁碟塊,開啟的fifo總是與乙個核心緩衝區相關聯,這一緩衝區中臨時存放兩個或多個程序之間交換的資料。

在linux2.6中,fifo和管道幾乎是相同的,並使用相同的pipe_inode_info結構。事實上只有兩點主要差別:

fifo索引節點出現在系統目錄樹上而不是pipefs特殊檔案系統中。

fifo是一種雙向通訊管道;也就是說,可能以讀/寫模式開啟乙個fifo。

ipc是程序間通訊(interprocess communication)的縮寫,通常指允許使用者態程序執行下列操作的一組機制:

通過訊號量與其他程序進行同步。

向其他程序傳送資訊或者從其他程序接收資訊。

和其他程序共享一段記憶體區。

ipc資料結構是在程序請求ipc資源(訊號量、訊息佇列或者共享記憶體區)時動態建立的。每個ipc資源都是持久的:除非被程序顯示的釋放,否則永遠駐留在記憶體中(直到系統關閉)。ipc資源可以由任一程序使用,包括那些不共享祖先程序所建立的資源的程序。

根據新資源是訊號量、訊息佇列還是共享記憶體區,分別呼叫semget()、msgget()或者shmget()函式建立ipc資源。

注意,程序之間另乙個通訊通道的存在並不基於ipc。

ipc訊號量與核心訊號量非常相似:二者都是計數器,用來為多個程序共享的資料結構提供受控訪問。

如果受保護的資源是可用的那麼訊號量的孩子就是正數;如果受保護的資源現在不可用,那麼訊號量的值就是0。要訪問資源的程序試圖把訊號量的值減一,但是,核心阻塞這個程序,直到在這個訊號量是的操作產生乙個正值。當程序是受保護資源時,就把訊號量的值增加一;在這樣處理的過程中,其他所有正在等待這個訊號量的程序就都被喚醒。

程序之間可以通過ipc訊息進行通訊。程序產生的每條訊息都被傳送到乙個ipc訊息佇列中,這個訊息一直存放在佇列中直到另乙個程序將其讀走為止。

訊息是由固定大小的首部和可變長度的正文組成的,可以使用乙個整數值(訊息型別)標識訊息,這就允許程序有選擇地從訊息佇列中獲取訊息。只要程序從ipc訊息佇列讀出一條訊息,核心就把這個訊息刪除;因此,只能有乙個程序接收一條給定的訊息。

最有用的ipc機制是共享記憶體,這種機制允許兩個或多個程序通過把公共資料結構放入乙個共享記憶體區(ipc shared memory region)來訪問他們。如果程序要訪問這種存放在共享記憶體區的資料結構,就必須在自己的位址空間中增加乙個新記憶體區,它將對映與這個共享記憶體區先關的頁框。這樣的頁框很容易地由核心通過請求調頁進行處理。

1.更簡單的基於檔案的應用介面。

2.完全支援訊息優先順序(優先順序最終決定佇列中訊息的位置)。

3.完全支援訊息到達的非同步通知,這通過訊號或是執行緒建立實現。

4.用於阻塞傳送與接收操作的超時機制。

以上內容來自

《深入理解linux核心》一書。

UNIX 程序間通訊

linux繼承了at t和bsd以及早期的程序間的通訊 一般常用的通訊方式有 1 傳統的通訊方式 無名管道,有名管道和訊號。2 對於sys 5 的程序間通訊採用了共享記憶體,訊息佇列和訊號燈的形式。3 bsd,對於一般網路間的通訊採用來套接字的方式實現。1 無名管道的機制以及建立 對於無名管道只是用...

unix程序間通訊

程序間通訊主要可以分為兩大類 1.傳遞控制資訊 程序間的低階通訊 2.傳送大批量資料 程序間的高階通訊 主要的通訊方式主要有 1.主從式通訊方式 master servant communication 通訊的程序雙方存在一種主從式的隸屬關係。主程序是程序的控制者,從程序是程序的從屬者。主要有以下特...

Unix程序間的通訊

1.管道可以用作父子程序之間的通訊,pipe函式,將fd 0 開啟用於讀取資料,fd 1 開啟用於寫入資料。通常,對於單方向通訊,讀端會關閉寫fd,即fd 1 寫端會關閉讀fd,即fd 0 int main read fd 0 buf,30 sleep 2 write stdout fileno,b...