程序間通訊 訊息佇列

2021-08-03 03:24:08 字數 3486 閱讀 3812

訊息佇列

訊息佇列提供了一種從乙個程序向另乙個程序傳送資料塊的方法。每個資料塊都被認為是有乙個型別,接收者程序接收的資料塊可以有不同的型別值。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是基於位元組流的,且訊息佇列的讀取不一定是先入先出。訊息佇列與命名管道有一樣的不足,就是每個訊息的最大長度是有上限的,每個訊息佇列的總的位元組數是有上限的,系統上訊息佇列的總數也有乙個上限。

ipc物件資料結構

核心為每個ipc物件維護了乙個資料結構:

struct ipc_perm
訊息佇列結構

struct msqid_ds ; 

第乙個條目就是ipc結構體,

訊息佇列,共享記憶體,訊號量都有乙個這樣共同的資料結構。後面的都是訊息佇列所 私  有的成員。訊息佇列是用鍊錶來實現的。

在linux中使用訊息佇列

linux提供了一系列的訊息佇列的函式介面來讓我們方便地使用它來實現程序間的通訊。它的用法與其他兩個system  v ipc機制,即訊號量和共享記憶體相似。

1.msgget函式:該函式用來建立和訪問乙個訊息佇列。

原型:int msgget(key_t key , int msg***)

與其他ipc機制一樣,程式必須提供乙個鍵來命名某個特定的訊息佇列,key可以認為是乙個埠號,也可以由ftok生成。msg***是乙個許可權標誌,表示訊息佇列的訪 問許可權,它與檔案的訪問許可權一樣。ipc_creat表示如果ipc不存在,則建立乙個ipc資源,否則開啟操作;ipc_excl只有在共享記憶體不存在的時候,新的共享記憶體才建立,否則就產生錯誤。如果將ipc_creat和ipc_excl標誌一起使用,***get()將返回乙個新建的ipc識別符號,若該資源已存在,返回-1。ipc_exel標誌本身並沒有太大的意義,但和ipc_creat標誌一起使用可以用來保證所得的物件都是新建的,而不是已有的物件。

2.msgrcv函式:從佇列中取用訊息

原型:sszie_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msg***)

msgsnd函式:將資料放到訊息佇列中

原型:int msgsnd(int msqid,const void *msgp,size_t msgsz,int msg***)

msqid是訊息佇列的標識碼,msgp指向訊息緩衝區的指標,此位置用來暫時儲存傳送和接收的訊息,是乙個使用者可定義的通用結構,形態如下:

struct msgstru

msgsz訊息的大小。msgtyp從訊息佇列內讀取訊息形態,如果值為零,則表示訊息佇列中的所有訊息都會被讀取。 msg***用來指明核心程式在佇列沒有資料的情況下所應採取的行動。如果msg***和常數ipc_nowait合用,則在msgsnd()執行時若是訊息佇列已滿,則msgsnd()將不會阻塞,而會立即返回-1,如果執行的是msgrcv(),則在訊息佇列呈空時,不做等待馬上返回-1,並設定錯誤碼為enomsg。當msgflag為0時,msgsnd()及msgrcv()在佇列呈滿或呈空的情形時,採用阻塞等待的處理模式。

3.msgctl函式:設定訊息佇列屬性。

原型:int msgctl(int msgqid,int cmd,struct msqid_ds *buf)

msgctl系統呼叫對msgqid標識的訊息佇列執行cmd操作,系統定義了3種cmd操作:ipc_stat:該命令用來獲取訊息佇列對應的msqid_ds資料結構,並將其儲存到buf指定的位址空間;ipc_set:該命令用來設定訊息佇列的屬性,要設定的屬性儲存在buf中;ipc_rmid:從核心中刪除msqid標識的訊息佇列。

下面我們來看下面**,server.c建立訊息佇列,接收資料,client.c傳送資料。

#ifndef _comm_h

#define _comm_h

#include#include#include#include#include#include#define pathname "."

#define proj_id 0x6666

#define server_type 1

#define client_type 2

struct msgbuf;

int creat_msgqueue();

int get_msgqueue();

int delete_msgqueue(int msg_id);

int senddata_to_msgqueue(int msg_id,int sendtype,char* msg);

int recdata_to_msgqueue(int msg_id,int recetype,char* out);

#endif

#include"comm.h"

static int commcreat_msgqueue(int flags)

int msg_id=msgget(key,flags);

if(msg_id<0)

return msg_id;

}int creat_msgqueue()

int get_msgqueue()

int senddata_to_msgqueue(int msg_id,int sendtype,char* msg)

return 0;

}int recdata_to_msgqueue(int msg_id,int recetype,char* out)

strcpy(out,buf.mtext);

return 0;

}int delete_msgqueue(int msg_id)

return 0;

}

#include"comm.h"

int main()

else

} return 0;

}

#include"comm.h"

int main()

buf[s-1]=0;

senddata_to_msgqueue(msg_id,client_type,buf);

printf("send done,wait receive...\n");

recdata_to_msgqueue(msg_id,server_type,buf);

printf("server#%s\n",buf);

} delete_msgqueue(msg_id);

return 0;

}

上面的的程式用訊息佇列實現了程序間通訊,下面我們在兩個終端下檢視執行結果:

以上就是關於訊息佇列的簡單介紹,若有不足,請指出。

程序間訊息佇列通訊

要保證server能夠接收client的訊息,就必須保證server的生成的msg的識別符號是一樣的,也就是兩個用的key是必須一樣的。msglucy.c include include include include include include include include include ...

程序間通訊(訊息佇列)

在嵌入式linux應用開發中,linux程序通訊的方式有6種,分別是管道 pipe 及有名管道 named pipe 訊號 signal 訊息佇列 msg 共享記憶體 shm 訊號量 和套接字 socket 在這我就簡單的描述一下程序通訊中的資訊佇列 msg 首先,訊息佇列的實現有重要的幾步 1 建...

程序間通訊 訊息佇列

有三種稱作xsi ipc的ipc 訊息佇列 訊號量以及 共享記憶體。它們只見有很多的相似之處。訊息佇列是訊息的鏈結表,儲存在核心中,由訊息佇列識別符號表示。它不同於管道,其生命週期是隨核心的。訊息佇列提供了 一種從 乙個程序向另 乙個程序傳送 乙個資料塊的 方法。每個資料塊都被認為是有 乙個型別,接...