Linux程序間通訊

2021-08-07 01:49:51 字數 3746 閱讀 6166

1、資料傳輸:乙個程序需要將它的資料傳送給另乙個程序。

2、資源共享:多個程序之間共享同樣的資源。

3、通知事件:乙個程序需要向另乙個或一組程序傳送資訊,通知它們發生了某種事情。

4、程序控制:有些程序希望完全控制另乙個程序。此時控制程序能夠攔截另乙個程序的所有操作,並能夠及時知道它的狀態改變。

管道是單向的、先進先出的、無結構的、固定大小的位元組流。

建立管道:呼叫pipe函式在核心開闢一塊緩衝區,稱為管道,pipe函式呼叫成功返回1,失敗返回0。

1、它有乙個讀端乙個寫端。

2、通過filedes引數傳出給使用者程式兩個檔案描述符:filedes[0]指向讀端,filedes[1]指向寫端。

3、向這個檔案讀寫資料其實是在讀寫核心緩衝區。

4、單個管道只能單向通訊,一端用於讀,而另一端用於寫。如果要實現程序雙向通訊,必須建立一對管道。

管道的侷限性:

1、歷史上,管道是半全雙工,(即資料只能在乙個方向上流動,只能是一端寫,一端讀)。

2、只能在有公共祖先的程序之間使用(在父子程序或兄弟程序間使用)——普通管道。

3、讀資料的同時也將資料從管道移走,因此,管道不能用來對多個接受者廣播資料。

4、管道中的資料被當做位元組流,因此無法識別資訊的邊界。

5、如果乙個管道有多個讀程序,那麼寫程序不能傳送資料到指定的讀程序,同樣,如果有多個寫程序,那麼沒有辦法判斷是哪乙個傳送資料。

建立命名管道的系統函式有兩個:mkfifo和mknod,呼叫成功返回0,失敗返回-1,兩個函式的原型如下:

通訊:

1、父程序呼叫pipe函式開闢管道,得到兩個檔案描述符分別指向管道的兩端。

2、父程序呼叫fork函式建立子程序,同樣子程序也有兩個檔案描述符指向該管道的兩端。

3、父程序關閉讀端,子程序關閉寫端,父程序可以往管道裡寫,子程序可以從管道中讀,管道是用環形佇列實現的,資料從寫端流入讀端流出,這樣就實現程序間通訊。

linux必須保證管道的寫和讀步調一致:linux使用鎖、等待佇列、和訊號實現同步。

訊息佇列提供從乙個程序到另乙個程序傳送資料塊的方法。

訊息佇列與管道的區別:

1、訊息佇列是基於訊息的,管道是基於位元組流的。

2、訊息佇列傳送訊息來避免管道的同步和阻塞問題。

3、訊息佇列的讀取不一定是先進先出。

4、每個訊息佇列的最大長度有上限,給定訊息總的位元組數有上限,訊息佇列總訊息數有上限。

核心為每個ipc物件維護乙個資料結構,都包括ipc_perm資料結構。(訊息佇列、訊號量、共享記憶體都有這個資料結構)。

struct ipc_perm

;訊息佇列就是乙個訊息的乙個鍊錶,允許乙個或多個程序向它寫訊息,乙個或多個程序從中讀訊息。

linux提供訊息佇列的操作:

1、建立或獲得訊息佇列:

函式原型:

int sys_msgget (key_t key, int msg***);

引數:key:

是乙個鍵值,可以認為是乙個埠號,也可以由函式ftok生成。

msg***:是乙個標誌。

msg***:

ipc_creat:如果ipc不存在,則建立乙個ipc資源,否則開啟操作。

ipc_excl:  ipc_creat和ipc_excl可以保證所得物件是新建的,而不是開啟的已有物件。

工作過程如下:

1) 如果key == ipc_private,則申請一塊記憶體,建立乙個新的訊息佇列( 資料結構msqid_ds),將其初始化後加入到msgque向量表中的某個空位置處,返回識別符號。

2) 在msgque向量表中找鍵值為key的 訊息佇列,如果沒有找到,結果有二:

a、 msg***表示不建立新的佇列,則錯誤返回。

b、 msg***表示要建立新的佇列,則建立新 訊息佇列,建立過程如1)。

3) 如果在msgque向量表中找到了鍵值為key的 訊息佇列,則有以下情況:

a、如果msg***表示一定要建立新的 訊息佇列而且不允許有相同鍵值的佇列存在,則錯誤返回。

b、如果找到的佇列是不能用的或已損壞的佇列,則錯誤返回。

c、認證和訪問許可權檢查,如果該佇列不允許msg***要求的訪問,則錯誤返回。

d、正常,返回佇列的 識別符號。

2、向佇列讀/寫訊息

函式原型:

該函式做如下工作:

1) 該 訊息佇列在向量msgque中的索引是id = (unsigned int) msqid % msgmni,認證檢查(許可權、模式),合法性檢查(型別、大小等)。

2) 如果 佇列已滿,以可中斷等待狀態(task_interruptible)將當前程序掛起在wwait 等待佇列上。

3) 申請一塊空間,大小為乙個訊息 資料結構加上訊息大小,在其上建立乙個訊息資料結構struct msg,將訊息緩衝區中的訊息內容拷貝到該記憶體塊中訊息頭的後面(從 使用者空間拷貝到 核心空間)。

4) 將訊息資料結構加入到 訊息佇列的隊尾,修改佇列的相應引數(大小等)。

5) 喚醒在該 訊息佇列的rwait程序佇列上等待讀的程序。

6) 返回。

msgrcv:

該函式做如下工作:

1) 該訊息佇列在向量msgque中的索引是id = (unsigned int) msqid % msgmni,認證檢查(許可權、模式),合法性檢查。

2)根據msgtyp和msg***搜尋 訊息佇列,情況有二:

3)如果找不到所要的訊息,則以可中斷等待狀態(task_interruptible)將當前程序掛起在rwait等待佇列上。

4)如果找到所要的訊息,則將訊息從 佇列中摘下,調整佇列引數,喚醒該 訊息佇列的wwait程序佇列上等待寫的程序,將訊息內容拷貝到 使用者空間的訊息緩衝區msgp中,釋放核心中該訊息所占用的空間,返回。

訊號量的本質是一種資料操作鎖,它本身不具有資料交換的功能,而是通過控制其他的通訊資源來實現程序間通訊,它本身只是一種外部資源的標識。訊號量在此過程中負責資料操作的互斥、同步等功能。

使用訊號量的原因:為了防止出現多個程式同時訪問乙個共享資源引發的一系列問題。任一時刻只能有乙個執行執行緒訪問**的臨界區域。

訊號量只能進行兩種操作等待和傳送訊號即p(sv)和v(sv)。

通常由乙個程序建立。其他程序對這個記憶體進行讀寫,得到共享記憶體通常是通過記憶體對映。

linux本身無法對其同步,需要程式自己來對共享記憶體做出同步計算,何種同步很多時候就是用訊號量實現的。

Linux程序間通訊

程序間通訊 ipc interprocess communication 基本機制 訊號 管道及命名管道 訊息佇列 共享主存 訊號量 套接字。訊號 全稱軟中斷訊號,是在軟體層次上對中斷機制的一種模擬,它也是程序間通訊機制中唯一的非同步通訊機制。linux訊號處理函式可分為訊號安裝函式 訊號傳送函式和...

Linux程序間通訊

謝謝nonoob糾錯 我們在linux訊號基礎中已經說明,訊號可以看作一種粗糙的程序間通訊 ipc,interprocess communication 的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種 1.管道與...

Linux程序間通訊

謝謝nonoob糾錯 我們在linux訊號基礎中已經說明,訊號可以看作一種粗糙的程序間通訊 ipc,interprocess communication 的方式,用以向程序封閉的記憶體空間傳遞資訊。為了讓程序間傳遞更多的資訊量,我們需要其他的程序間通訊方式。這些程序間通訊方式可以分為兩種 1.管道與...