消息队列 msg

目录

1.消息队列的原理

2.消息队列的接口:

2.1创建消息队列

2.2发送消息

2.3接收消息

2.4操作消息队列的接口

3 消息队列的生命周期也是跟随操作系统


1.消息队列的原理

  • 1.1msgqueue采用链表来实现消息队列,该链表是由系统内核维护。
  • 1.2系统中可能有很多的msgqueue, 每个MQ用消息队列描述符(消息队列ID: qid) 来区分,qid是唯一的,用来区分不同的MQ。
  • 1.3在进行进程间通信时,一个进程将消息加到MQ尾端,另一个进程从消息队列中取消息(不一定以先进先出来取消息,也可以按照消息类型字段取消息。这样就实现了进程间的通信
  • 队列 : 先进先出,只要满足先进先出特性的数据结构都可以称之为队列。
  •  

2.消息队列的接口:

2.1创建消息队列

  • int msgget (key_ t key , int msgflg);
  • 参数:
    • key:消息队列的标识符
    • msgflg:创建的标志,
    • 例如IPC_CREAT
    • IPC_ CREAT :如果不存在,则创建,按位或(|)权限(8进制的数字就可以了)
  • 返回值:
    • 成功:返回队列ID
    • 失败:返回-1,并设置erron

2.2发送消息

  • int msgsnd(int msqid , const void *msgp,size_ t msgsz , int msgflg) ;
  • 扫描二维码关注公众号,回复: 14467433 查看本文章
  • 参数:
    • msqid:消息队列ID
    • msgp:指向msgbuf 的指针,用来指定发送的消息
    • 操作系统为该函数发送的消息定义了发送格式,只是定义了一 部分,另外一 部分还需要程序员自己定义。
    • msgsz:要发送消息的长度(消息内容的长度)
    • msgf1g:创建标记,
      • 如果指定IPC _NOWAIT,失败会立刻返回
      • 0 :阻塞发送
      • IPC_ NOWAIT :非阻塞放松.
    • 返回值:
      • 成功返回0
      • 失败返回-1,并设置erron

2.3接收消息

  • ssize_ t msgrcv(int msqid , void *msgp, size_t msgsz , long msgtyp ,int msgflg) ;
  • 参数:
    • msgid:消息队列ID
    • msgp:指向msgbuf 的指针,用来接收消息
    • msgsz:要接收消息的长度
    • 注意:参数msgsz 指定由msgp 参数指向的结构的成员mtext 的最大大小(以字节为单位),msgtyp 也有3种方式:
    • msgtyp:接收消息的方式
      • 1.msgtyp=0:读取队列中的第一条消息
      • 2. msgtyp > 0:读取队列中类型为msgtyp 的第一条消息,
      • 若在msgflg 中指定了MSG_ EXCEPT,将读取类型不等于msgtyp的队列中的第一条消息(为了获取除了msgtyp之外的其他元素,获取其他元素的时候,按照先进先出的特性)。
      • 3. msgtyp < 0: 读取队列中最小类型小于或等于msgtyp 绝对值的第一 条消息
    • msgf1g:创建标记,如果指定IPC_NOWAIT,获取失败会立刻返回
      • 0 :阻塞发送
      • IPC_ NOWAIT :非阻塞放松.
  • 返回值:
    • 成功返回实际读取消息的字节数,
    • 失败返回-1,并设置erron

2.4操作消息队列的接口

  • int msgctl(int msqid, int cmd, struct msqid_ ds *buf) ;
    • 参数:
      • msqid:消息队列ID
      • cmd:控制命令,
        • 例如IPC_ RMID,删除命令
        • IPC STAT,获取状态
      • buf:存储消息队列的相关信息的buf
    • 返回值:
      • 成功,根据不同的cmd有不同的返回值,
      • 失败返回-1,并设置erron
  • 代码验证
    • 1.拥有一个消息队列(不管是哪一个进程创建出来的),不同进程想要使用消息队列继续通信的时候,只需要获取同样的消息队列标识符就可以了
    • 2.一个进程发送,一个进程接收
    • 发送:
    • #include <stdio.h>
      #include <unistd.h>
      #include <sys/msg.h>
      #include <string.h>
      struct msgbuf {
      long mtype;       /* message type, must be > 0 */
      char mtext[127];    /* message data */
      };
      int main(){
      //1.获取或创建消息队列
      int que_id=msgget(0x12123434,IPC_CREAT|0664);
      if(que_id<0){
      perror("msgget:");
      return 0;
      }
      printf("masgqueue ID is :%d\n",que_id);
      //2.组织要发送的消息
      for(int i=0;i<10;i++){
      struct msgbuf mb;
      mb.mtype=i+1;
      const char*msg="i am send msg prcess...";
      sprintf(mb.mtext,"%s %d",msg,i+1);
      //strcpy(mb.mtext,msg);
      //3。发送
      msgsnd(que_id,&mb,sizeof(mb.mtext),0);
      }
      for(int i=0;i<10;i++){
      struct msgbuf mb;
      mb.mtype=i+1;
      const char*msg="i am send msg prcess...";
      sprintf(mb.mtext,"%s %d",msg,i+1);
      //strcpy(mb.mtext,msg);
      //3。发送
      msgsnd(que_id,&mb,sizeof(mb.mtext),0);
      }
      return 0;
      }

    • 接收:
    • #include <stdio.h>
      #include <unistd.h>
      #include <sys/msg.h>
      #include <string.h>
      struct msgbuf {
      long mtype;       /* message type, must be > 0 */
      char mtext[127];    /* message data */
      };
      int main(){
      //1.获取或创建消息队列
      int que_id=msgget(0x12123434,IPC_CREAT|0664);
      if(que_id<0){
      perror("msgget:");
      return 0;
      }
      printf("masgqueue ID is :%d\n",que_id);
      //2
      struct msgbuf mb;
      mb.mtype=1;
      //3。接收
      msgrcv(que_id,&mb,sizeof(mb.mtext),3,0);
      printf("msgrcv:%s\n",mb.mtext);
      return 0;
      }

    • ipcs命令查看消息队列

3 消息队列的生命周期也是跟随操作系统

猜你喜欢

转载自blog.csdn.net/sy2453/article/details/123648589
今日推荐