Linux 学习笔记18 消息队列

Linux 学习笔记18 消息队列

消息队列概念

消息队列与 FIFO 很相似,都是一个队列结构,都可以有多个进程往队列里面写信息,多个进程从队列中读取信息。但 FIFO 需要读、写的两端事先都打开,才能够开始信息传递工作。而消息队列可以事先往队列中写信息,需要时再打开读取信息。

  • 消息队列与管道的不同之处

图1

图2

消息队列常用函数

创建消息队列

  •  int msgget(key_t key, int msgflg);
    

参数解析:

  • key 是唯一标识一个消息队列的关键字,如果为 IPC_PRIVATE(值为 0),用创建一个只有创建者进程才可以访问的消息队列,可以用于父子间通信;
  • msgflg 指明队列的访问权限和创建标志,创建标志的可选值为 IPC_CREAT和 IPC_EXCL

msgget 代码如下:

#include <func.h>
  //获取消息队列                                                                                              
 int main(int argc,char * argv[])
  {
      int msgid;
      int ret;
      msgid=msgget(1000,IPC_CREAT|0600);//消息队列大小由系统默认设置
     ERROR_CHECK(ret,-1,"msgget");
      return 0;
  }

执行效果如下:
msgget

msqid:消息队列id
used-bytes : 已往消息队列写入的数据

发送消息队列 msgsnd

  •  int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
    

参数解析:

  • msqid:消息队列id, msgget的返回值
  • msgp:变长结构体,需自己定义,详细如下
  •  struct msgbuf {
            long mtype;       /* message type, must be > 0 */  //消息类型
            char mtext[1];    /* message data */  //消息大小,自定义
        };
    
  • msgsz:消息队列大小
  • msgflg:一般填0

接收消息队列 msgrcv

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

参数解析

  • msqid:消息队列id, msgget的返回值
  • msgp:变长结构体同上
  • msgsz:同上
  • msgtype :消息类型,在结构体 msgbuf 中已定义
  • msgflg :同上。

msgsnd && msgrcv 代码如下:

#include <func.h>
  
  typedef struct msgbuf_b{
      //变长结构体
      long mtype;
      char mtext[128];
  }MSG;
int main(int argc,char * argv[])
  {
      int msgid;
      int ret;
      MSG msg;
      msgid=msgget(1000,IPC_CREAT|0600);//消息队列大小由系统默认设置
      if(!fork())
      {//子进程读
          msg.mtype=1;//消息类型设置为1
          strcpy(msg.mtext,"I am Jarvis\n");
          ret=msgsnd(msgid,&msg,strlen(msg.mtext),0);
          ERROR_CHECK(ret,-1,"msgsnd");
          printf("Child mark send %d bytes\n",ret);//正确返回0,错误返回-1
      }else
      {//父进程写
          bzero(&msg,sizeof(msg));
          ret=msgrcv(msgid,&msg,sizeof(msg.mtext),1,0);//第4个参数填0时按顺序读队列,填1时读type为1的节点
          printf("ret=%d,type=%ld,%s\n",ret,msg.mtype,msg.mtext);                                             
          wait(NULL);
      }   
      return 0;
  }

执行效果如下:

msgsnd和msgrcv

  • 只往消息队列中发送,没有接受的情况:
#include <func.h>
  //验证只发送不接收,消息会存放在消息队列中
  //
  typedef struct msgbuf_b{
  //变长结构体
      long mtype;
      char mtext[128];
  }MSG;
 int main(int argc,char * argv[])
  {
      int msgid;
      int ret;
      MSG msg;
      msgid=msgget(1000,IPC_CREAT|0600);//消息队列大小由系统默认设置
      msg.mtype=1;
      strcpy(msg.mtext,"I am Jarvis\n");
      ret=msgsnd(msgid,&msg,strlen(msg.mtext),0);
      ERROR_CHECK(ret,-1,"msgsnd");
      return 0;                                                                                               
  }

执行效果如下:
msgsnd

由图可知,往消息队列中写入 12 个字节,因此 used-bytes 变为12。

补充:删除消息队列命令

  •  ipcrm -q 消息队列ID
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值