1. 程式人生 > >Linux-程序間通訊(訊息對列)

Linux-程序間通訊(訊息對列)

今天來介紹IPC通訊的第一種方式:訊息對列

由於程序具有獨立性,要想兩個程序之間有資料的往來,就必須讓兩個不相干的程序看到同一塊資源。前面有講到管道,也是一種公共資源。現在,我們介紹一種另一種公共資源:訊息對列

訊息對列,顧名思義,想必看到的公共資源可能就是一種佇列。這種佇列滿足資料結構裡佇列的特點:先進先出。

訊息對列提供了一個程序向另一個程序傳送一塊資料快的通訊方法,注意,是以塊為基本單位,前面的管道是以位元組流為基本單位。

每個資料塊都被認為是由型別的。接收者程序接受資料塊可以有不同的型別值,比如可以是結構體型。
每個訊息 佇列的最大長度是上限的(MSGMAX),每個訊息佇列的總的位元組數也是有上限的(MSGMNB),系統的訊息佇列總數也是有上線的(MSGMNI),
這裡寫圖片描述

為了便於理解,我畫了一個簡圖
這裡寫圖片描述

認識訊息佇列結構

  • 作業系統為每個IPC物件都維護了一個數據結構

檢視命令:

[zyc@localhost /]$ cat ./usr/include/linux/ipc.h

這裡寫圖片描述

  • 檢視訊息佇列結構

[zyc@localhost /]$ cat ./usr/include/linux/msg.h

這裡寫圖片描述
這裡寫圖片描述

訊息佇列函式

msgget函式

功能:建立和訪問訊息佇列
原型:


 #include <sys/types.h>
 #include <sys/ipc.h>
 #include <sys/msg.h>
int
msgget(key_t key, int msgflg); 引數: key:某個訊息佇列的名字 msgflg:有九個許可權標識位組成,他們的用法和建立檔案時使用的mode模式是一樣的 返回值: 成功返回一個非負整數,即該訊息佇列的識別碼,即msgid,給使用者看。失敗返回-1

這裡解釋一下標識位

IPC_CREAT:如果檔案不存在,則建立一個新檔案,如果存在,把存在的檔案描述符返回
IPC_EXCL:沒有任何實際意義,只在建立時使用,與IPC_CREAT進行或運算:IPC_CREAT|EXCL,則會建立一個全新的檔案。

再解釋一下 key,通過“ftok”函式獲得。函式呼叫成功時,即通過它,就可以找到訊息對列。

下面來看ftok函式介紹

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

作用:獲得訊息對列識別符號。兩個互相獨立的程序要進行通訊,就必須都可以看到這個標誌符。程序A和程序B都可以看到。

引數自己定製,一般定義在標頭檔案中,採用巨集定義方式。一般路徑採用當前路徑,proj_id設定0x666

返回值:成功返回訊息對列標誌符(給核心看),失敗返回-1。

msgctl函式

作用:訊息對列的控制函式
原型:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

引數
    msqid:msgget函式的返回值,即訊息佇列識別碼
    cmd:有三個動作
返回值
    成功返回0,失敗返回-1

cmd的三個動作:

命令 說明
IPC_STST
IPC_SET
IPC_RMID 刪除訊息佇列

msgsend函式

功能:把一條訊息加入訊息對列中
原型

#include <sys/types.h>
 #include <sys/ipc.h>
  #include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

引數:
    msgid:由msgget函式返回的訊息對列標誌碼
    msgp:,是一個指標指向即將傳送的訊息
    msgsz:是msgp指向的訊息佇列長度
    msgflg:控制著當前訊息對列到達系統上限即將發生的事情。
    msgflg==IPC+NOWAIT表示對列不等待。返回EAGAIN錯誤。
返回值:成功返回0,失敗返回-1

1:訊息結構在兩方面受到制約:

  • 他必須小於系統規定的上限值;
  • 它必須以一個long int長整數開始,接受者將按照這個長整數確定訊息的型別

2,訊息結構參考如下
這裡寫圖片描述

msgrcv函式

功能:從一個訊息佇列中接收訊息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
引數:
    msgid:由msgget函式返回的訊息對列標誌碼

    msgp:,是一個指標指向即將傳送的訊息
    msgsz:是msgp指向的訊息佇列長度
    msgtype:他可以實現接收優先順序的簡單形式
    msgflg:控制著訊息佇列中沒有相應型別訊息可供接收時將要發生的事情。
返回值:
    成功返回0,失敗返回-1

mytype=0:返回佇列第一條訊息
mytype>0:返回佇列第一條型別等於中mytype的訊息
mytype<0:返回佇列中第一條型別小於mytype絕對值的訊息,並且是滿足條件的訊息型別最小訊息。
mytype=IPC_NOWAIT,佇列沒有訊息不等待,返回ENOMSG錯誤
mytype=MSG_MOERROR,訊息超過msgsize是將會被截斷。
mytype>0且msgflg=MSG_EXCEPT,接受型別不等於msgtype的第一條訊息。

下面我們將要來編寫實際程式碼來實現基於訊息對列的程序間通訊。

ipcs命令和ipcrm命令

ipcs 顯示IPC資源

這裡寫圖片描述



ipcs -q :檢視已存在訊息對列
ipcrm -q (msgid)    :刪除指定訊息對列