1. 程式人生 > >POSIX IPC之訊息佇列

POSIX IPC之訊息佇列

使用訊號和管道傳遞訊息存在一定的限制:訊號傳遞的訊息有限,管道雖然可以傳輸一定量的資訊,但是隻能傳遞無格式的位元組流。3種新的程序間通訊(IPC)機制---訊息佇列、訊號量、共享記憶體,可以解決這些問題。這些機制最早出現在UNIX中,被編入POSIC:XSI中,Linux支援POSIX標準。 (1)關於IPC資源 訊息佇列、訊號量、共享記憶體都是IPC資源,這些資源在使用之前都需要先建立。Linux核心中,IPC資源都可以使用一個非負整數——IPC識別符號(訊息佇列識別符號、訊號量識別符號、共享記憶體識別符號)來進行標識。 在建立一個IPC識別符號之前,需要指定一個關鍵字key,可以呼叫函式ftok()獲得。 int ftok(const char *pathname, int prj_id);//失敗返回-1 (2)關於訊息佇列 訊息佇列實際上就是一個連結串列(工作就是倒騰連結串列的,從來沒倒騰過這種,o(∩_∩)o...),而訊息就是連結串列中具有特定格式和優先順序的記錄,程序可以根據一定規則在訊息連結串列中新增訊息,需要訊息的程序則可以從訊息佇列中獲得所需的資訊。 訊息寫入訊息佇列時,系統會將訊息加入到訊息佇列維護的訊息連結串列中。如圖所示: msg_next------| msg_type       |------>msg_next------| msg_ts                       msg_type       |------>msg_next msg_spot|                  msg_ts                   | -訊息      msg_spot---訊息 msg_next:下一個訊息指標 msg_type:訊息型別,使用者自己定義 msg_ts:訊息長度 msg_spot:訊息內容 (3)訊息佇列相關函式 1、建立訊息佇列:int msgget(key_t key,int msgflag) 該函式用於建立或者訪問訊息佇列,獲得訊息佇列識別符號符。key就是上面用ftok()獲得的IPC關鍵字。 2、獲得/修改訊息佇列屬性:int msgctl(int msqid,int cmd,struct msqid_ds *buf); msqid為要修改、讀取屬性的訊息佇列識別符號, 引數cmd如果為IPC_STAT時表示讀取核心中記錄訊息佇列資訊的資料結構msqid_ds, 返回的訊息佇列屬性存放在buf指向的結構體中。 3、訊息傳送:int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg); msqid:要將訊息傳送的訊息佇列識別符號 msgp:指標指向訊息結構體msgbuf typedef struct {     long msgtype;  //訊息型別,任何大於0的整數,自定義     char mtext[?]; //訊息文字,文字大小由msgsnd中的msgsz決定  }msgbuf; msgsz:訊息位元組數 msgflg:可以為0(忽略該引數)或者IPC_NOWAIT(如果訊息佇列沒有足夠空間,如果設定了IPC_NOWAIT,立刻返回;否則函式阻塞,直到等到空間)。 4、訊息接收:int msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg); 從msqid代表的訊息佇列取出訊息,存放在msgp指向的緩衝區,緩衝結構定義和傳送時使用的msgbuf類似; msgsz:訊息內容長度,msgbuf結構體中mtext的長度; msgtpye:請求讀取的訊息型別 msgflg:引數可以取0,也可以取IPC_NOWAIT等。如果為IPC_NOWAIT時,訊息佇列如果為空,則函式阻塞,直到有訊息可以取。 (4)例項: 【建立訊息佇列、發訊息】 程式碼儲存systemcall2.c #include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h> #define BUF_SIZE 100 typedef struct {
 long mtype;
 char mtext[BUF_SIZE];
}msg_info;   //用於訊息傳送 //建立訊息佇列 int creat_msg_queue()
{
 int proj_id = 1;
 int msg_id;
 key_t key;
 
 key = ftok("/home/gaolu",proj_id);  //建立IPC識別符號,需要先獲得一個key
 if(-1 == key)
 {
  perror("Can't generate the IPC key.\n");
  return -1;
 }  msg_id = msgget(key,IPC_CREAT|0660); //如果msg_id不存在,則建立,否則,返回已經存在的佇列識別符號
 if(-1 == msg_id)
 {
  printf("Can't creat message queue resource.\n");
  return -1;
 }
 
 return msg_id;
} //向佇列發訊息 int send_msg(int msg_id,char* message)
{
 int result;
 msg_info MsgInfo;
 
 MsgInfo.mtype = 10;
  //隨意定義,大於0 && 整數 即可
 strcpy(MsgInfo.mtext,message);  result = msgsnd(msg_id,&MsgInfo,strlen(message),0);
 if(-1 == result)
 {
  perror("Fail to send message to message queue.\n");
 }
 return result;
} //顯示訊息資訊|驗證訊息是否發入佇列 int show_msg_queue_stat(int msg_id)
{
 struct msqid_ds MsgQueueInfo;
 int result;
 
 result = msgctl(msg_id,IPC_STAT,&MsgQueueInfo); //獲得訊息佇列資訊(所有者,許可權,訊息數……)
 if(-1 == result)
 {
  perror("Can't get status of message queue.\n");
  return -1;
 } 
 printf("======================Message Queue Info=======================\n");
 printf("Effective user id: %d.\n",MsgQueueInfo.msg_perm.uid);
 printf("Effective user group id: %d.\n",MsgQueueInfo.msg_perm.gid);
 printf("Current numbers of bytes in message queue(non-standard): %ld.\n",MsgQueueInfo.__msg_cbytes);
 printf("Current numbers of message in message queue: %ld.\n",MsgQueueInfo.msg_qnum);
 printf("===============================================================\n");  return 0;
} int main(void)
{
 int msg_id; 
 int result;
 msg_id = creat_msg_queue();
 send_msg(msg_id,"Test data..............");
 show_msg_queue_stat(msg_id);
 return 0; }
【取訊息】 程式碼儲存msgrcv.c #include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h> #define BUF_SIZE 100 typedef struct {
 long mtype;
 char mtext[BUF_SIZE];
}msg_info; //讀取訊息佇列中指定型別的訊息,將訊息內容儲存在msg指向的地址空間 int rcv_msg(int msg_id,int msg_type,char* msg)
{
 int result;
 msg_info MsgInfo;  result = msgrcv(msg_id,&MsgInfo,BUF_SIZE,msg_type,0);
 if(-1 == result)
 {
  perror("Can't receive message from message queue.\n");
  return result;
 }
 strcpy(msg,MsgInfo.mtext);
 return result;
}
int main(int argc,char* argv[])
{
 int result;
 char message[BUF_SIZE];
 int msg_type;
 int msg_id;
 if(3 != argc)
 {
  printf("Useage:%s msgid msg_type.\n",argv[0]);
  return -1;
 }
 msg_type = atoi(argv[2]);
 msg_id = atoi(argv[1]); //獲得指定型別訊息並顯示訊息內容
 result = rcv_msg(msg_id,msg_type,message);
 if(-1 == result)
 {
  perror("Fail to receive message.\n");
 }
 else
 {
  printf("Message: %s.\n",message);
 }
 return result; 
}
【執行結果】
[email protected]:~$

[email protected]:~$
[email protected]:~$ gcc -o msgq systemcall2.c
[email protected]:~$ gcc -o rcv msgrcv.c
[email protected]:~$ ./msgq
======================Message Queue Info=======================
Effective user id: 1000.
Effective user group id: 1000.
Current numbers of bytes in message queue(non-standard): 23.
Current numbers of message in message queue: 1.
================================================================
[email protected]:~$

[email protected]:~$ ipcs -q  //IPC命令 引數q表示訊息佇列(m:共享記憶體,s:訊號量) ------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages   
0x01018b15 0          gaolu      777        23           1          

相關推薦

POSIX IPC訊息佇列

使用訊號和管道傳遞訊息存在一定的限制:訊號傳遞的訊息有限,管道雖然可以傳輸一定量的資訊,但是隻能傳遞無格式的位元組流。3種新的程序間通訊(IPC)機制---訊息佇列、訊號量、共享記憶體,可以解決這些問題。這些機制最早出現在UNIX中,被編入POSIC:XSI中,Linux支援POSIX標準。 (1)關於I

程序間通訊(IPC)訊息佇列

★IPC方法包括管道(PIPE)、訊息佇列(Message_Queue)、旗語、共用記憶體(ShareMemory)以及套接字(Socket)。進 程間通訊主要包括了管道、系統IPC(包括了訊息佇列、

Linux IPC 訊息佇列

認識訊息佇列 訊息佇列提供了從一個程序到另一個程序傳送一個數據塊(整發整收)的能力。 每個資料塊被認為有一個應用型別, 接收者程序接受的資料塊可以有不同的型別。 訊息佇列的每一個傳送和接收的資料塊是有最大位元組限制的(MSGMAX), 整個訊息佇列的大小也

Linux---程序間通訊IPC訊息佇列

**程序間通訊(IPC):**是指在不同程序之間傳播或交換資訊。 **IPC的方式:**通常有管道(無名管道、命名管道)、訊息佇列、訊號量、共享儲存、Socket、Streams等(Socket和Streams支援不同主機上的兩個程序IPC) 程序間通訊的目

IPC訊息佇列詳解與使用

一、    概念  訊息佇列就是一個訊息的連結串列。對訊息佇列有寫許可權的程序可以向其中按照一定的規則新增新訊息;對訊息佇列有讀許可權的程序可以從訊息佇列中讀出訊息。訊息佇列是隨核心持續的。下面介紹三個概念: 1;隨程序持續:IPC一直存在,直至開啟IPC物件的最後一個程序

UNIX網路程式設計:IPC訊息佇列

訊息佇列:將訊息佇列按佇列的方式組織成的連結串列,每個訊息都是其中的一個節點; 注意:訊息佇列的長度及每個訊息的大小是有限制的 訊息佇列的操作函式如下: msgget   int msgget(key_t key,int msgflg);  

IPC訊息佇列

什麼是訊息佇列 訊息佇列提供了一種從一個程序向另一個程序傳送一個數據塊的方法。每個資料塊都被認為是有一個型別,接收者今晨會二手的資料塊可以有不同的型別值。我們可以通過傳送訊息來避免命名管道的同步和阻塞問題。訊息佇列與管道不同的是,訊息佇列是基於訊息的,而管道是

IPC通訊------------訊息佇列詳解

訊息佇列(也叫做報文佇列)能夠克服早期unix通訊機制的一些缺點。作為早期unix通訊機制之一的訊號能夠傳送的資訊量有限,後來雖然POSIX 1003.1b在訊號的實時性方面作了拓廣,使得訊號在傳遞資訊量方面有了相當程度的改進,但是訊號這種通訊方式更像"即時"的通訊方式,它要

IPC通訊訊息佇列、訊號量和共享記憶體

    有三種IPC我們稱作XSI IPC,即訊息佇列,訊號量以及共享儲存器。XSI IPC源自System V的IPC功能。由於XSI IPC不使用檔案系統的名稱空間,而是構造了它們自己的名字空間,

【Linux】程序間通訊(IPC訊息佇列詳解及測試用例

學習環境 Centos6.5 Linux 核心 2.6 什麼是訊息佇列? 訊息佇列是SystemV版本中三種程序通訊機制之一,另外兩種是訊號量和共享儲存段。訊息佇列提供了程序間傳送資料塊的方法,而且每個資料塊都有一個型別標識。訊息佇列是基於訊息的,而管

ThreadX——IPC應用訊息佇列

> - 作者:zzssdd2 > > - E-mail:[email protected] # 一、應用簡介 `訊息佇列`是RTOS中常用的一種資料通訊方式,常用於任務與任務之間或是中斷與任務之間的資料傳遞。在裸機系統中我們通常會使用全域性變數的方式進行資料傳遞,比如在事件發生後在中

Redis訊息佇列

SpringBoot 結合redis實現訊息佇列功能 釋出者: 配置連線工廠 @Bean public StringRedisTemplate template(RedisConnectionFactory connectionFactory){ retu

日誌系統訊息佇列的應用

kafka的概述 Kakfa是由LinkedIn公司開發的一個分散式的訊息系統,後成為Apache頂級開源專案,它使用Scala編寫,以可水平擴充套件和高吞吐率的特性而被廣泛使用。 ps: 通過上述百度百科的概述,只知其然而不知其所以然。 kafka 大家都知道是訊息佇列,那麼籠統的說訊息佇列是

Cris 玩轉大資料系列訊息佇列神器 Kafka

Cris 玩轉大資料系列之訊息佇列神器 Kafka Author:Cris 文章目錄 Cris 玩轉大資料系列之訊息佇列神器 Kafka Author:Cris 1. Kafka 概述

Java架構訊息佇列 (一):訊息佇列的概述

訊息佇列系列分享大綱:  一、訊息佇列的概述 二、訊息佇列之RabbitMQ的使用 三、訊息佇列之Kafka的使用 四、訊息佇列之RabbitMQ的原理詳解 五、訊息佇列之Kafka的原理詳解 六、訊息佇列之面試集錦 1.訊息佇列的概述 訊息佇列(Me

Java程式設計師從笨鳥到菜鳥(五十四) 分散式訊息佇列

##目錄 該文只是一個複習思路,不瞭解訊息佇列的人建議先看《訊息佇列從入門到精通》 ##一、為什麼使用訊息佇列 三個最主要的應用場景:解耦、非同步、削峰 1、解耦 傳統模式: 缺點:系統間的耦合性太強,如上圖示,系統 A 在程式碼中直接呼叫系統 B 和

嵌入式Linux併發程式設計,程序間通訊方式,System V IPC訊息佇列,開啟/建立msgget(), 傳送訊息msgsnd(),格式,接收訊息msgrcv(),控制訊息佇列 msgctl()

文章目錄 1,訊息佇列 2,訊息佇列結構 3,訊息佇列使用步驟 3.1,開啟/建立訊息佇列 msgget() 3.1.1,開啟/建立訊息佇列---示例msgget() 3.2,向訊息佇列傳送訊息 msgs

分散式訊息佇列複習精講

文章轉自www.cnblogs.com/rjzheng/p/8994962.html 引言 為什麼寫這篇文章? 博主有兩位朋友分別是小A和小B: 小A,工作於傳統軟體行業(某社保局的軟體外包公司),每天工作內容就是和產品聊聊需求,改改業務邏輯。再不然就是和運營

視訊第13章(高併發訊息佇列思路)

1、訊息佇列 訊息佇列已經逐漸成為企業IT系統內部通訊的核心手段。它具有低耦合、可靠投遞、廣播、流量控制、最終一致性等一系列功能,成為非同步RPC的主要手段之一。 訊息被處理的過程相當於流程A被處理。我們這裡以一個實際的模型來討論下,比如使用者下單成功時給使

【Linux】Linux程序間通訊訊息佇列

1、訊息佇列概念引入    訊息佇列提供了一個從一個程序向另外一個程序傳送一塊資料的方法每個資料塊都被認為是有一個型別,接收者程序接收的資料塊可以有不同的型別值訊息佇列也有管道一樣的不足,就是每個訊息的最大長度是有上限的(MSG