lv5 嵌入式开发-11 消息队列

news2024/11/28 1:28:24

掌握:消息队列机制、打开/创建消息队列、发送消息、接收消息

1 消息队列

消息队列是System V IPC对象的一种

消息队列由消息队列ID来唯一标识

消息队列就是一个消息的列表。用户可以在消息队列中添加消息、读取消息等

消息队列可以按照类型来发送/接收消息

消息队列结构

内核中已实现的数据结构:链表

进程A放入数据,进程B可访问并取出。

2 消息队列使用步骤 

发送端:

        1 申请key

        2 打开/创建消息队列   msgget

        3 向消息队列发送消息   msgsnd

接收端:

        1 打开/创建消息队列   msgget

        2 从消息队列接收消息   msgrcv

        3 控制(删除)消息队列   msgctl

2.1 消息队列创建/打开 – msgget

#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
  • 成功时返回消息队列的id,失败时返回EOF  
  • key 和消息队列关联的key  IPC_PRIVATE 或 ftok  
  • msgflg  标志位  IPC_CREAT|0666  没有创建,有则打开。

示例

int main() {
   int msgid;
   key_t key;

   if ((key = ftok(“.”, ‘q’)) == -1) {
      perror(“ftok”);  exit(-1);
   }
   if ((msgid = msgget(key, IPC_CREAT|0666)) < 0) {
      perror(“msgget”); exit(-1);
   }
   …… 
   return 0;
}

2.2 消息发送 – msgsnd

#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msgid, const void *msgp, size_t size,
            int msgflg);
  • 成功时返回0,失败时返回-1  
  • msgid   消息队列id  
  • msgp    消息缓冲区地址  
  • size    消息正文长度  
  • msgflg   标志位 0 或 IPC_NOWAIT

        0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列

        IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回

2.3 消息格式

  • 通信双方首先定义好统一的消息格式
  • 用户根据应用需求定义结构体类型
  • 首成员类型必须为long,代表消息类型(正整数)
  • 其他成员都属于消息正文
  • 消息长度不包括首类型 long

示例:

typedef  struct {
   long mtype;
   char mtext[64];
} MSG;

#define LEN (sizeof(MSG) – sizeof(long))

int main() {
    MSG buf;
    ……
    buf.mtype = 100; 
    fgets(buf.mtext, 64, stdin);
    msgsnd(msgid, &buf,LEN, 0);
    …… 
    return 0;
}

注意:

1 消息结构必须有long类型的msg_type字段,表示消息的类型。

2消息长度不包括首类型 long

 

2.4 消息接收 – msgrcv

 #include <sys/ipc.h>
 #include <sys/msg.h>
 int msgrcv(int msgid, void *msgp, size_t size, long msgtype,
                   int msgflg);
  • 成功时返回收到的消息长度,失败时返回-1  
  • msgid   消息队列id  
  • msgp   消息缓冲区地址  
  • size   指定接收的消息长度  
  • msgtype   指定接收的消息类型    
  • msgflg   标志位   0 或 IPC_NOWAIT        

        msgtype=0:收到的第一条消息,任意类型。

        msgtype>0:收到的第一条 msg_type类型的消息。

        msgtype<0:接收类型等于或者小于msgtype绝对值的第一个消息

例子:如果msgtype=-4,只接受类型是1、2、3、4的消息

示例 

typedef  struct {
    long mtype;
    char mtext[64];
}MSG;

#define  LEN  (sizeof(MSG) – sizeof(long))

int main() {
    MSG buf;
    ……
    if (msgrcv(msgid, &buf,LEN, 200, 0) < 0) {
       perror(“msgrcv”);
       exit(-1);
    }
    ……
}

2.5 控制消息队列 – msgctl

#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msgid, int cmd, struct msqid_ds *buf);
  • 成功时返回0,失败时返回-1  
  • msgid    消息队列id  
  • cmd    要执行的操作  IPC_STAT / IPC_SET / IPC_RMID  (删除)
  • buf   存放消息队列属性的地址

2.6 示例(编写实现两个进程实现消息队列通信的程序)

 示例:发送消息队列

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

typedef struct{
    long msg_type;
    char buf[128];
}msgT;    

#define MSGLEN  (sizeof(msgT)-sizeof(long))

int main(){
    key_t key;
    int msgid;
    int ret;
    msgT msg;
    key = ftok(".",100);                //创建key
    if(key<0){
        perror("ftok");
        return 0;
    }
    msgid = msgget(key,IPC_CREAT|0666);  //创建消息队列
    if(msgid<0){
        perror("msgget");
        return 0;
    }

    msg.msg_type = 1;
    strcpy(msg.buf,"this msg type 1");
    ret = msgsnd(msgid,&msg,MSGLEN,0);
    if(ret<0){
        perror("msgsnd");
        return 0;
    }    

    msg.msg_type = 2;
    strcpy(msg.buf,"this msg type 2");
    ret = msgsnd(msgid,&msg,MSGLEN,0);
    if(ret<0){
        perror("msgsnd");
        return 0;
    }
    msg.msg_type = 3;
    strcpy(msg.buf,"this msg type 3");
    ret = msgsnd(msgid,&msg,MSGLEN,0);
    if(ret<0){
        perror("msgsnd");
        return 0;
    }
    msg.msg_type = 4;
    strcpy(msg.buf,"this msg type 4");
    ret = msgsnd(msgid,&msg,MSGLEN,0);
    if(ret<0){
        perror("msgsnd");
        return 0;
    }
    msg.msg_type = 5;
    strcpy(msg.buf,"this msg type 5");
    ret = msgsnd(msgid,&msg,MSGLEN,0);
    if(ret<0){
        perror("msgsnd");
        return 0;
    }

}

查看消息队列 

示例:消息接收和删除

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

typedef struct{
    long msg_type;
    char buf[128];
}msgT;    

#define MSGLEN  (sizeof(msgT)-sizeof(long))
int main(){
    
    int msgid;
    key_t key;
    msgT msg;
    int ret;
    key = ftok(".",100);
    if(key<0){
        perror("ftok");
        return 0;
    }    
    msgid = msgget(key,IPC_CREAT|0666);
    if(msgid<0){
        perror("msgget");
        return 0;
    }
    int count=0;           
    while(1){     //连续接收
        //ret = msgrcv(msgid,&msg,MSGLEN,3,0);   //只接收类型3
        //ret = msgrcv(msgid,&msg,MSGLEN,-3,0);   //只接收类型1、2、3
        ret = msgrcv(msgid,&msg,MSGLEN,0,0);     //全部接收
        if(ret<0){ 
            perror("msgrcv");
            return 0;
        } 
        count++;
        if(count>3){
            break;
        }
        printf("receiv msg type=%d,buf=%s\n",(int)msg.msg_type,msg.buf);
    }

    ret = msgctl(msgid,IPC_RMID,NULL);
    if(ret<0){
        perror("msgctl");
        return 0;
    }    

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win10自带输入法怎么删除-Win10卸载微软输入法的方法

Win10自带输入法怎么删除&#xff1f;Win10系统自带输入法就是微软输入法&#xff0c;这个输入法满足了很多用户的输入需求。但是&#xff0c;有些用户想要使用其它的输入法&#xff0c;这时候就想删除掉微软输入法。下面小编给大家介绍最简单方便的卸载方法吧。 Win10卸载微软…

数据挖掘(1)概述

一、数据仓库和数据挖掘概述 1.1 数据仓库的产生 数据仓库与数据挖掘&#xff1a; 数据仓库和联机分析处理技术(存储)。数据挖掘&#xff1a;在大量的数据中心挖掘感兴趣的知识、规则、规律、模式、约束(分析)。数据仓库用于决策分析&#xff1a; 数据仓库&#xff1a;是在数…

在Qt中,怎么获取到在mainwindow.ui文件中添加的控件

2023年9月30日&#xff0c;周六晚上 假设我在mainwindow.ui中添加了一个名为textEdit的QTextEdit对象 在mainwindow.cpp中&#xff0c;可以通过ui对象来获取到这个控件

妙不可言的Python之旅----(一)

初识Python python的起源 1989年&#xff0c;为了打发圣诞节假期&#xff0c;Gudio van Rossum吉多 范罗苏姆&#xff08;龟叔&#xff09;决心开发一个新的解释程序&#xff08;Python雏形&#xff09; 1991年&#xff0c;第一个Python解释器诞生 Python这个名字&#xff…

怎么修改jupyter lab 的工作路径而不是直接再桌面路径打开

要修改Jupyter Lab的工作路径&#xff0c;你可以按照以下步骤操作&#xff1a; 打开终端或命令提示符窗口。 输入 jupyter lab --generate-config 命令来生成Jupyter Lab的配置文件。 找到生成的配置文件&#xff0c;通常会位于 ~/.jupyter/jupyter_notebook_config.py。 使…

C++ AB组辅导课

C AB组辅导课 蓝桥杯C AB组辅导课 第一讲 递归与递推 Acwing1、整数划分(递归)2、acwing92. 递归实现指数型枚举10凑算式(全排列)11李白打酒(全排列)12、棋牌总数(递归)13、剪邮票(递归)14、1050. 鸣人的影分身 (递归或动态规划(记忆化搜索))15、方格分割 &#xff08;dfs思维&…

蓝桥杯每日一题2023.9.30

蓝桥杯大赛历届真题 - C&C 大学 B 组 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 对于此题&#xff0c;首先想到了dfs进行一一找寻&#xff0c;注意每次不要将重复的算进去&#xff0c;故我们每次循环可以记录一个开始的位置&#xff0c;下一次到这个位置时&#xff0c;…

Git版本控制系统

概念&#xff1a; 一个免费的 开源 分布式源码仓库&#xff0c;帮助团队维护代码 个人使用 多人联机使用 git安装: 这里直接看大佬的安装 文章 很不错的 git 安装配置https://blog.csdn.net/mukes/article/details/115693833 安装完毕之后&#xff1a; 使用命名git -v查看…

腾讯云最新优惠活动汇总!来看看腾讯云最近都有哪些优惠活动!

腾讯云作为国内领先的云服务提供商之一&#xff0c;经常推出各种优惠活动来吸引用户&#xff0c;本文将为大家汇总腾讯云最新的优惠活动&#xff0c;希望能够帮助大家降低上云成本&#xff0c;提高用户上云体验。 一、腾讯云新用户优惠券【点击领取】 腾讯云针对新用户推出了…

mysql面试题6:MySQL索引的底层原理,是如何实现的?B+树和B树的区别?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL索引的底层原理,是如何实现的? MySQL索引的底层实现是通过B+树来实现的。B+树是一种多叉平衡查找树,它的特点是能够高效地支持数据的插入…

300多元耳机推荐哪个牌子好、性价比最高的开放式耳机推荐

随着蓝牙耳机产业的迅猛发展&#xff0c;目前最备受欢迎的蓝牙耳机类型之一就是开放式耳机。与传统的耳塞式蓝牙耳机相比&#xff0c;开放式耳机具备诸多优势&#xff0c;包括长时间佩戴的舒适性和安全性。开放式耳机不需要插入耳朵&#xff0c;也能提供音乐欣赏的体验&#xf…

【C++】多态面试题

&#x1f680;write in front&#x1f680; &#x1f4dc;所属专栏&#xff1a; C学习 &#x1f6f0;️博客主页&#xff1a;睿睿的博客主页 &#x1f6f0;️代码仓库&#xff1a;&#x1f389;VS2022_C语言仓库 &#x1f3a1;您的点赞、关注、收藏、评论&#xff0c;是对我最大…

【AIGC核心技术剖析】研究报告分享与汇总

AIGC研究报告 AI画画工具项目参考 AIGC&#xff08;Artificial General Intelligence Control&#xff09;技术是一种人工智能&#xff08;AI&#xff09;技术&#xff0c;旨在管理和控制人工智能系统的行为&#xff0c;以确保它们在执行任务时遵守一定的规则、伦理和价值观。A…

c进阶--指针进阶

&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c;&#x1f33c; 指针的简单回顾&#x1f33c;&#x1f33c;&#x1f33c;&#x…

助企上云新举措!移动云网盘服务平台正式上线

近日&#xff0c;移动云网盘服务平台&#xff08;DSP&#xff09;V1.0重磅发布。DSP作为移动云首个自研aPaaS平台&#xff0c;具备多存储节点纳管、高效文件管理、极速文件传输、多媒体数据处理、一体化运维支撑等功能特性&#xff0c;可满足文档管理、内容协作、云上会议、数据…

9.30消息队列

发送方&#xff1a; #include<myhead.h>//消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小int main(int argc, const char *argv[]) {//1.创建key值key_t key;if(…

国庆9.30

消息队列实现进程间通信 snd #include <myhead.h> //消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小int main(int argc, const char *argv[]) {//1、创建key…

中国1km分辨率逐月降水数据集(1901-2020)

佳节 中国逐月降水量数据集&#xff08;1901-2021&#xff09;是根据CRU发布的全球0.5气候数据集以及WorldClim发布的全球高分辨率气候数据集&#xff0c;通过Delta空间降尺度方案在中国地区降尺度生成的。使用了496个独立气象观测点数据进行验证&#xff0c;验证结果可信。数…

模块化CSS

1、什么是模块化CSS 模块化CSS是一种将CSS样式表的规则和样式定义封装到模块或组件级别的方法&#xff0c;以便于更好地管理、维护和组织样式代码。这种方法通过将样式与特定的HTML元素或组件相关联&#xff0c;提供了一种更具可维护性、可复用性和隔离性的方式来处理样式。简单…

在MyBatisPlus中添加分页插件

开发过程中&#xff0c;数据量大的时候&#xff0c;查询效率会有所下降&#xff0c;这时&#xff0c;我们往往会使用分页。 具体操作入下&#xff1a; 1、添加分页插件&#xff1a; package com.zhang.config;import com.baomidou.mybatisplus.extension.plugins.Pagination…