一、雞肋
1、訊號通訊,能夠傳送的資訊量有限。管道通訊,則只能傳送無格式的位元組流。這都無疑會給應用程式的開發帶來不便。
2、訊息佇列(又叫報文隊列),則客服了這些缺點。
訊息佇列就是一個訊息的鏈表。可以把訊息看作是一個記錄,具有特定的格式。
寫進程可以向其中按照一個的規則添加訊息;讀進程則可以從訊息佇列中讀訊息;注意:和管道一樣,當讀進程從訊息佇列中讀走一個訊息後,該訊息會從訊息佇列中刪除
3、訊息佇列的分類:
(1)POSIX(可移植作業系統介面)訊息佇列
(2)系統V(system v,這個V念five)訊息佇列,目前用的比較多
4、System V中的訊息佇列的特性
(1)持久性,system v訊息佇列是隨核心持續的,只有在核心重啟或者人工刪除時,該訊息佇列才會被刪除
(2)索引值,由於訊息佇列的核心持久性,要求每個訊息佇列都在系統範圍內對應唯一的索引值,所以當要獲得一個訊息佇列的描述符時,就必須提供該訊息佇列的索引值
二、訊息佇列通訊
1、索引值:
(1)引入標頭檔:
#include<sys/types.h>,#include<sys/ipc.h>
(2)key_t ftok(char * pathname,char proj); file to key
怎麼用:
i、返迴文件名對應的索引值
==pathname:檔案名稱
==proj:項目名,不為0就行
2、建立/開啟(意思是msgget函數建立和開啟操作用的是同一個函數),訊息佇列
(1)int msgget(key_t key,int msgflg); message get,獲得訊息佇列的描述符
參數:
==key:索引值,由ftok獲得
==msgflg:標誌位,它的可以是
-- IPC_CREAT,如果key值對應的隊列不存在時,使用這個標識會建立新的訊息佇列
-- IPC_EXCL,與IPC_CREAT一同使用,表示如果要建立的訊息佇列已經存在則返回錯誤
-- IPC_NOWAIT,讀寫訊息佇列要求無法得到滿足時,不阻塞
傳回值:
與索引值key相對應的訊息佇列描述字
(2)msgget函數在以下兩種情況中會建立一個新的訊息佇列:
i、如果沒有與索引值key相對應的訊息佇列,並且msgflg中包含了IPC_CREAT標誌位
ii、key參數為IPC_PRIVATE
3、發送訊息:int msgsnd(int msqid,struct msgbuf * msgp,int msgsz,int msgflg);
怎麼用:
(1)參數:
== msqid,已經開啟的訊息佇列的id
== msgp,發送訊息的結構體類型
== msgsz,訊息資料長度
== msgflg,發送標誌,有意義的msgflg標誌為IPC_NOWAIT,指明在訊息佇列沒有足夠空間容納要發送的訊息時,msgsnd是否等待
(2)訊息的格式,注意不一定自己定義的訊息類型結構體也叫msgbuf,這裡只是一個例子,實際應用我們可以自行指定訊息的名字;另外這個訊息結構體類型中以下兩個成員是必須的:
struct msgbuf{
long mtype;//表明訊息的類型,可以自行指定,只要發送的類型和接受的類型一樣就可以。另外實際上mtype即用來標誌訊息的類型的成員的變數的名字也可以是任意的,系統只要求訊息結構體中第一個成員必須是一個整型的變數
char data[X];//訊息資料的首地址。資料的名字也是任意的,怎麼組合,eg訊息由data1[150],和data2[100],兩個數組組成
}
(3)說明:
i、一個訊息佇列中,可以存放多種類型的訊息,只要注意發送和接受時的訊息類型一樣就好
ii、
4、接受訊息:int msgrcv(int msqid,struct msgbuf * msgp,int msgsz,long msgtyp,int msgflg);
怎麼用:從msqid代表的訊息佇列中讀取一個msgtyp類型的訊息。並把訊息儲存在msgp執行的msgbuf結構中。當成功的讀取了一條訊息後,隊列中的這條訊息將被刪除