Linux消息队列整理

消息队列和有名管道一样,都是文件,因此为获取消息队列的键值,我们可以通过ftok(函数)将文件转化为键值

#include

#include

key_t ftok(char*pathname, int id)

功能:返回文件名对应的键值

pathname:文件名(含路径)

id:项目名(不为0即可)


10.1打开/创建消息队列

10.1.1 函数名

msgget

10.1.2 函数原形

int msgget(key_t key,int msgflg) 

10.1.3 函数功能

获取/创建一个消息队列标识符

10.1.4 所属头文件

10.1.5 返回值

成功:返回消息队列标识符  失败:返回-1

10.1.6 参数说明

key:与消息文件对应的键值,由ftok获取

msgflg:标志位

    IPC_CREAT:创建新的消息队列

    IPC_EXCL:与IPC_CREAT一同使用,表示如果要创建的消息队列已经存在,则返回错误

    IPC_NOWAIT:读写消息队列要求无法得到满足,不阻塞

在以下两种情况下,将创建一个新的消息队列

  1.如果没有与键值key相对应的消息队列,并且msgflg中包含了IPC_CREAT标志位。

  2.key参数为IPC_PRIVATE

 

创建消息队列

int open_queue(key_t keyval)

{

    intqid;

if((qid=mesget(keyval,IPC_CREATE))==-1)

    return(-1);

return (qid); 

}

 

10.2向消息队列发送消息(操作消息队列)

10.2.1 函数名

msgsnd

10.2.2 函数原形

int msgsnd(int msqid,struct msgbuf*msgp,size_t msgsz,int msgflg)

10.2.3 函数功能

向消息队列中发送一条消息

10.2.4 所属头文件

10.2.5 返回值

成功:返回0  失败:返回-1

10.2.6 参数说明

msqid:已打开的消息队列id

msgp:存放消息的结构

struct msgbuf

{

    long mtype;//消息类型>0

    char mtext[1];/*消息数据的首地址*/

 }

msgsz:消息数据长度

msgflg:发送标志,有意义的msgflg标志为IPC_NOWAIT,指明在消息队列没有足够空间容纳要发送的消息时,msgsnd是否等待


10.3从消息队列中取消息

10.3.1 函数名

msgrcv

10.3.2 函数原形

int msgrcv(int msqid,structmsgbuf *msgp,size_t msgsz,long  msgtyp,

int msgflg)

10.3.3 函数功能

从msqid代表的消息队列中读取一个msgtyp类型的消息,并把消息存储在msgp指向的msgbuf结构中。在成功地读取了一条消息以后,队列中的这条消息将被删除

10.3.4 所属头文件

10.3.5 返回值

成功:返回0  失败:返回-1

10.3.6 参数说明

msqid:待取消息队列中消息的id

msgp:存放消息的结构

struct msgbuf{ long mtype;//消息类型>0

                char mtext[1];/*消息数据的首地址*/  }

msgsz:消息数据长度

msgtyp:待取消息的类型,与发送消息的的结构体成员msgbuf.mtype相对应,消息队列中可以有不同的消息,通过该参数来确定收哪种消息;一个类型可以存取多条消息,按先进先出的规则,从消息队列中取出该消息

msgflg:接收标志,通常为:IPC_NOWAIT

接收消息代码(demo)

int read_message(int qid,long type,structmymsgbuf*qbuf)

    intresult,length;

length=sizeof(struct mymsgbuf)-sizeof(long);//消息的长度

//等价于length = sizeof(mymsgbuf.data);

if((result=msgrcv(qid,qbuf,length,type,0))==-1)

  return(-1);

return(result);


10.4综合代码
#include
#include
#include
#include

struct msg_buf
{
   int mtype;
   char data[255];
};

int main()
{
   key_t key;
   int msgid;
   int ret;
   struct msg_buf msgbuf;
   
   key = ftok("/tem",'a');
   printf("key = [%x]\n",key);
   msgid = msgget(key,IPC_CREAT|0666);/*通过文件对应*/	
   
   if (msgid == -1)
   {
      printf("creat error\n");
      return -1;	
   }
   
   msgbuf.mtype = getpid();//getpid()获取当前进程的PID,并将该值赋给mtype
   strcpy(msgbuf.data,"test haha");
   ret = msgsnd(msgid, &msgbuf, sizeof(msgbuf.data), IPC_NOWAIT);
   if(ret == -1)
   {
      printf("send message error\n");
      return -1;	
   }
   
   memset(&msgbuf,0,sizeof(msgbuf));
   ret = msgrcv(msgid, &msgbuf, sizeof(msgbuf.data), getpid(), IPC_NOWAIT);
   if(ret == -1)
   {
     printf("receive message error\n");
     return -1;	
   }
   printf("recv msg = [%s]\n",msgbuf.data);
   printf("recv msg = %s\n",msgbuf.data);
   
}
运行结果:



 


你可能感兴趣的:(Linux,C)