程序間通訊之訊息佇列 Linux

2021-08-20 16:25:09 字數 3838 閱讀 9217

一、什麼是訊息

訊息(message

)是乙個格式化的可變長的資訊單元。訊息機制允許由乙個程序給其它任意的程序傳送乙個訊息。當乙個程序收到多個訊息時,可將它們排成乙個訊息佇列。

1、訊息機制的資料結構

(1)訊息首部

記錄一些與訊息有關的資訊,如訊息的型別、大小、指向訊息資料區的指標、訊息佇列的鏈結指標等。

(2)訊息佇列頭表

其每一項作為乙個訊息佇列的訊息頭,記錄了訊息佇列的有關資訊,如指向訊息佇列中第乙個訊息和指向最後乙個訊息的指標、佇列中訊息的數目、佇列中訊息資料的總位元組數、佇列所允許訊息資料的最大位元組總數,還有最近一次執行傳送操作的程序識別符號和時間、最近一次執行接收操作的程序識別符號和時間等。

2、訊息佇列的描述符

unix中,每乙個訊息佇列都有乙個稱為關鍵字(

key)的名字,是由使用者指定的;訊息佇列有一訊息佇列描述符,其作用與使用者檔案描述符一樣,也是為了方便使用者和系統對訊息佇列的訪問。

二、涉及的系統呼叫

下面的函式使用的標頭檔案:

#include

#include

#include

1.

msgget(

)建立乙個訊息,獲得乙個訊息的描述符。

系統呼叫格式:

int

msgqid=msgget(key,flag)

引數定義

key_t

key;

int

flag;

key是使用者指定的訊息佇列的名字;

flag

是使用者設定的標誌和訪問方式。如

ipc_creat |0400

是否該佇列已被建立。無則建立,是則開啟;

ipc_excl |0400        

是否該佇列的建立應是互斥的。

msgqid

是該系統呼叫返回的描述符,失敗則返回-1。

2

. msg

snd()

傳送一訊息。向指定的訊息佇列傳送乙個訊息,並將該訊息鏈結到該訊息佇列的尾部。

系統呼叫格式:

int

msgsnd(msgqid,msgp,size,flag)

引數定義: i

nt msgqid,size,flag;

struct msgbuf

* msgp; 其中

msgqid

是返回訊息佇列的描述符;

msgp

是指向使用者訊息緩衝區的乙個結構體指標,包括訊息型別和訊息正文,即

size

指示由msgp

指向的字元陣列的長度;即訊息的長度。這個陣列的最大值由

msg-max()

系統可呼叫引數來確定。

flag

規定當核心用盡內部緩衝空間時應執行的動作

: 程序是等待,還是立即返回。若在標誌

flag

中未設定

ipc_nowait

位,則當該訊息佇列中的位元組數超過最大值時,或系統範圍的訊息數超過某一最大值時,呼叫

msgsnd

程序睡眠。若是設定

ipc_nowait

,則在此情況下,

msgsnd

立即返回。 對於

msgsnd(

),核心須完成以下工作:

(1)對訊息佇列的描述符和許可權及訊息長度等進行檢查。若合法才繼續執行,否則返回;

(2)核心為訊息分配訊息資料區。將使用者訊息緩衝區中的訊息正文,拷貝到訊息資料區;

(3)分配訊息首部,並將它鏈入訊息佇列的末尾。在訊息首部中須填寫訊息型別、訊息大小和指向訊息資料區的指標等資料;

(4)修改訊息佇列頭中的資料,如佇列中的訊息數、位元組總數等。最後,喚醒等待訊息的程序。

3

. msgrcv(

)接受一訊息。從指定的訊息佇列中接收指定型別的訊息。

系統呼叫格式:

int 

msgrcv(msgqid,msgp,size,type,flag)

引數定義:

int  msgqid,size,flag;

struct  msgbuf  *msgp;

long  type;

其中,msgqid,msgp,size,flag

與msgsnd

中的對應引數相似,

type

是規定要讀的訊息型別,

flag

規定倘若該佇列無訊息,核心應做的操作。如此時設定了ipc

_nowait

標誌,則立即返回,若在

flag

中設定了

ms_noerror

,且所接收的訊息大於

size

,則核心截斷所接收的訊息。 對於

msgrcv

系統呼叫,核心須完成下述工作:

(1)對訊息佇列的描述符和許可權等進行檢查。若合法,就往下執行;否則返回;

(2)根據

type

的不同分成三種情況處理:

type=0

,接收該佇列的第乙個訊息,並將它返回給呼叫者;

type

為正整數,接收型別

type

的第乙個訊息;

type

為負整數,接收小於等於

type

絕對值的最低型別的第乙個訊息。

(3)當所返回訊息大小等於或小於使用者的請求時,核心便將訊息正文拷貝到使用者區,並從訊息佇列中刪除此訊息,然後喚醒睡眠的傳送程序。但如果訊息長度比使用者要求的大時,則做出錯返回。

4

. msgctl( )

訊息佇列的操縱。讀取訊息佇列的狀態資訊並進行修改,如查詢訊息佇列描述符、修改它的許可權及刪除該佇列等。

系統呼叫格式:

int

msgctl(msgqid,cmd,buf);

引數定義:

int  msgqid,cmd;

struct  msgqid_ds  *buf;

其中,函式呼叫成功時返回0,不成功則返回-1。

buf是使用者緩衝區位址,供使用者存放控制引數和查詢結果;

cmd是規定的命令。命令可分三類:

(1)ipc_stat

。查詢命令。如查詢佇列中的訊息數目、佇列中的最大位元組數、最後乙個傳送訊息的程序識別符號、傳送時間等;

(2)ipc_set

。按buf

指向的結構中的值,設定和改變有關訊息佇列屬性的命令。如改變訊息佇列的使用者識別符號、訊息佇列的許可權等;

(3)ipc_rmid

。消除訊息佇列的識別符號。

msgqid_ds

結構定義如下:

struct  msgqid_ds ;

struct  ipc_perm

/*由系統使用*/ }

三、編寫程式

建立兩個子程序,子程序1建立乙個訊息佇列,並使用訊息機制向子程序2傳送一條訊息,傳送結束後輸出列印:data sent!  子程序2接收到訊息後,輸出列印接收的訊息字元,並輸出列印:data received!

#include #include #include #include #include #include #include #include #define msgkey 75

struct msgform

;void main( )

else //子程序2

}else         //子程序1

}

執行結果:

linux程序間通訊之訊息佇列

訊息佇列就是乙個訊息的鍊錶。可以把訊息看作乙個記錄,具有特定的格式以及特定的優先順序。對訊息佇列有寫許可權的程序可以向中按照一定的規則新增新訊息 對訊息佇列有讀許可權的程序則可以從訊息佇列中讀走訊息。include include include include include include in...

linux程序間通訊之訊息佇列

訊息佇列 使用訊息佇列的好處 可以給訊息附加特定的訊息型別。訊息佇列用於同一臺計算機的程序間的通訊。include include key t ftok const char pathname,int proj id 該函式根據檔名生成乙個id 系統建立ipc 通訊 訊息佇列 訊號量和共享記憶體 時...

Linux程序間通訊之訊息佇列

實現功能 編寫程式sender,它建立乙個訊息佇列 然後,迴圈等待使用者通過終端輸入一串字元,將這串字元通過訊息佇列傳送給receiver,直到使用者輸入 bye 為止 最後,它向receiver程序傳送訊息 end 並且等待receiver的應答,等到應答訊息後,將接收到的應答資訊顯示在終端螢幕上...