8、linux进程间通信之消息队列

本文介绍了消息队列的基本概念和发展历程,详细解释了其工作原理,包括如何创建、发送及接收消息,并提供了具体的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

                                                 消息队列

                     定义:

       Unix早期的通信机制之一的信号能够传送的信息量有限,管道则只能传      送无格式的字节流,这无疑会给应用程序的开发带来不便。消息队列(也叫报文队列)则克服了这些缺点。

                     发展

        消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式。进程可以向其中按照一定的规则添加新消息;另一些进程则可以从消息队列中读走消息

                     分类

Ø         POSIX消息队列

Ø         系统V消息队列

                     持续性

                            系统V消息队列是随内核持续的,只有在内核重启或者人工删除时,该消息队列才会被删除。

                     键值

                            消息队列的内核持续性要求每个消息队列都在系统范围内对应唯一的键值,所以,要获得一个消息队列的描述字,必须提供该消息队列的键值。

                            #include<sys/types.h>

                            #include<sys/ipc.h>

                            key_t ftok (char *pathname ,char proj)

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

                            Pathname :文件名

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

                     打开/创建

                            #include<sys/types.h>

                            #include<sys/ipc.h>

                            #include<sys/msg.h>

                            int msgget (key_t key , int msgflg)

                            key:键值。由ftok获得

                            msgflg:标志位

                        返回值:与键值key相对应的消息队列描述字。

                            标志位有:

²        IPC_CREAT 创建新的消息队列

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

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

 

                     创建

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

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

Ø         Key参数为IPC_PRIVATE

              创建:

                 int open_queue (key_t keyval)

                {

                        int qid;

                           If ((qid=msgget (keyval,IPC_CREAT))==-1)

                              {    

                                   return (-1); 

                              }

                                 return (qid);

                 }

 

               发送消息

                   #include<sys/types.h>

                  #include<sys/ipc.h>

                  #include<sys/msg.h>

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

                 功能:向消息队列中发送一条消息

 

   Ø         Msgid 已打开的消息队列的ID

   Ø         Msgp 存放消息的结构

   Ø         Msgsz 消息数据长度

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

                Struct msgbuf

                             {

                                   Long mtype; //消息的类型 >0

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

                              }

              接受消息:

             #include<sys/types.h>

               #include<sys/ipc.h>

             #include<sys/msg.h>

               int msgrcv (int msqid, struct msgbuf *msgp,int msgsz,long  msgtyp,int msgflg)

               功能

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

                int read_message(int qid,long type,struct mymsgbuf *qbuf)

                   {

                        int result,length;

                         length=sizeof(struct mymsgbuf)-sizeof (long);

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

                      return (-1);

                      return (result);

                  }

    例题:msg.c

                          #include <sys/types.h>

                        #include <sys/msg.h>

                        #include <unistd.h>

                        struct msg_buf

                     {

                          int mtype;

                         char data[255];

                       };

                    int main(){

                     key_t key;

                    int msgid;

                    int ret;

                  struct msg_buf msgbuf;

                  key=ftok("/tmp/2",'a');

                  printf("key =[%x]\n",key);

                  msgid=msgget(key,IPC_CREAT|0666); /*通过文件对应*/

                if(msgid==-1)

                 {

                     printf("create error\n");

                    return -1;

                    }

                  msgbuf.mtype = getpid();

                 strcpy(msgbuf.data,"test haha");

                  ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);

                  if(ret==-1)

                  {

                           printf("send message err\n");

                return -1;

                 }

            memset(&msgbuf,0,sizeof(msgbuf));    //内存设置。                         ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);

                         if(ret==-1)

                     {

                      printf("recv message err\n");

                      return -1;

                 }

                    printf("recv msg =[%s]\n",msgbuf.data);

                }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值