消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从

它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消息的传递;如果发送消息时

接收者不可用,消息队列会保留消息,直到可以成功地传递它。




msgget()函数被用来创建新的消息队列或获取已有的消息队列。其函数定义如下:


系统调用: msgget()
函数声明: int msgget ( key_t key, int msgflg )
返回值: message queue identifier on success
-1 on error: errno = EACCESS (permission denied)
EEXIST (Queue exists, cannot create)
EIDRM (Queue is marked for deletion)
ENOENT (Queue does not exist)
ENOMEM (Not enough memory to create queue)
ENOSPC (Maximum queue limit exceeded)
msgget()函数的第一个参数是消息队列对象的关键字(key),函数将它与已有的消息队
列对象的关键字进行比较来判断消息队列对象是否已经创建。而函数进行的具体操作是由
第二个参数,msgflg 控制的。它可以取下面的几个值:
IPC_CREAT :
如果消息队列对象不存在,则创建之,否则则进行打开操作;
IPC_EXCL:
和IPC_CREAT 一起使用(用”|”连接),如果消息对象不存在则创建之,否则产生一个
错误并返回。
如果单独使用IPC_CREAT 标志,msgget()函数要么返回一个已经存在的消息队列对象
的标识符,要么返回一个新建立的消息队列对象的标识符。如果将IPC_CREAT 和IPC_EXCL
标志一起使用,msgget()将返回一个新建的消息对象的标识符,或者返回-1 如果消息队列
对象已存在。IPC_EXCL 标志本身并没有太大的意义,但和IPC_CREAT 标志一起使用可
以用来保证所得的消息队列对象是新创建的而不是打开的已有的对象



函数原型

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

参数

msqid:消息队列的识别码。
msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下
struct msgbuf {
long mtype; /* 消息类型,必须 > 0 */
char mtext[1]; /* 消息文本 */
};
msgsz:消息的大小。
msgtyp:消息类型
msgtyp等于0 则返回队列的最早的一个消息。
msgtyp大于0,则返回其类型为mtype的第一个消息。
msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息。

msgflg:这个参数依然是是控制函数行为的标志,取值可以是:0,表示忽略;IPC_NOWAIT,如果消息队列为空,则返回一个ENOMSG,并将控制权交回调用函数的进程。如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件的消息为止。如果一个client 正在等待消息的时候队列被删除,EIDRM 就会被返回。如果进程在阻塞等待过程中收到了系统的中断信号,EINTR 就会被返回。MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,剩下的部分被丢弃了。如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被取出。当消息从队列内取出后,相应的消息就从队列中删除了。


读进程程序

#include 
#include 
#include 
#include 
#include 
#include "Ccommon.h"
#include 
int main()
{
  bool isRuning = true;
  struct shared_use_str pshared_use_str;
  int imsgget;
  long int msg_to_receive = 0;
  //创建或者链接一个已经存在的消息队列
  imsgget = msgget((key_t)1234,0666|IPC_CREAT);
        
  if(-1 == imsgget)
  {
      printf("msgget failed\n");
      exit(-1);
  }
        
        
  while(true == isRuning)
  {
    //读取消息队列内容
        if(msgrcv(imsgget,(void *)&pshared_use_str,BUFSIZ,msg_to_receive,0) == -1)
    {
        printf("failed to receive message\n");
        return -1;
    }
    printf("you enter %s\n",pshared_use_str.somedate);
    if(strncmp(pshared_use_str.somedate,"end",3) == 0)
    {
      isRuning = false;
    }  
  } 
  //删除消息队列
  if(msgctl(imsgget,IPC_RMID,0) == -1)
  {
    printf("msgctl failed\n");
    exit(-1);
  } 
        
        
  return 0;
}


写进程

#include 
#include 
#include 
#include 
#include 
#include "Ccommon.h"
#include 
#include 
int main()
{
  bool isRuning = true;
  struct shared_use_str pshared_use_str;
  int imsgget;
  //创建或者链接一个已经存在的消息队列
  imsgget = msgget((key_t)1234,0666|IPC_CREAT);
    
  if(-1 == imsgget)
  {
      printf("msgget failed\n");
      exit(-1);
  }
    
    
  while(true == isRuning)
  {
    printf("Enter som data\n");
    scanf("%s",pshared_use_str.somedate);
    //向消息队列发送消息
        if(msgsnd(imsgget, (void *) &pshared_use_str , 1000,0) == -1)
    {
        printf("failed to msgsnd message\n");
        return -1;
    }
    if(strncmp(pshared_use_str.somedate,"end",3) == 0)
    {
      isRuning = false;
    }  
  } 
    
    
  return 0;
}