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

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

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);                //创建keyif(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、3ret = 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.mzph.cn/news/91419.shtml

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

相关文章

Spring Boot:利用JPA进行数据库的增改

目录 JPA介绍Service接口Service和Autowired示例代码 Dao数据库操作层Repository示例代码 控制器文件示例代码-增加增加成功示例代码-修改修改成功 JPA介绍 JPA&#xff08;Javaa Persistence API)一种用于持久化 Java 对象到关系型数据库的标准规范。它提供了一种统一的方式来…

Pytorch单机多卡分布式训练

Pytorch单机多卡分布式训练 数据并行&#xff1a; DP和DDP 这两个都是pytorch下实现多GPU训练的库&#xff0c;DP是pytorch以前实现的库&#xff0c;现在官方更推荐使用DDP&#xff0c;即使是单机训练也比DP快。 DataParallel&#xff08;DP&#xff09; 只支持单进程多线程…

openGauss学习笔记-83 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用内存和存储规划

文章目录 openGauss学习笔记-83 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用内存和存储规划83.1 MOT内存规划83.2 存储IO83.3 容量需求 openGauss学习笔记-83 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用内存和存储规划 本节描述了为满足特定…

完整的 pixel 6a 刷入 AOSP 源码过程记录

基础环境 虚拟机&#xff1a;VMware Workstation 16 Pro 16.0.0 build-16894299 Linux版本&#xff1a;ubuntu-16.04.7-desktop-amd64 设备&#xff1a;pixel 6a&#xff1b;代号&#xff1a;bluejay&#xff1b; 基础软件安装 安装 Git 命令&#xff1a;sudo apt install git …

金融生产存储亚健康治理:升级亚健康 3.0 ,应对万盘规模的挑战

随着集群规模的不断扩大&#xff0c;硬盘数量指数级上升&#xff0c;信创 CPU 和操作系统、硬盘多年老化、物理搬迁等多种复杂因素叠加&#xff0c;为企业的存储亚健康管理增加了新的挑战。 在亚健康 2.0 的基础上&#xff0c;星辰天合在 XSKY SDS V6.2 实现了亚健康 3.0&#…

【C++入门到精通】C++入门 —— set multiset (STL)

阅读导航 前言一、set简介二、std::set1. std::set简介2. std::set的使用- 基本使用- std::set的模板参数列表- std::set的构造函数- std::set的迭代器- std::set容量与元素访问函数 3. set的所有函数&#xff08;表&#xff09; 三、std::multiset1. std::multiset简介 四、st…

嵌入式学习笔记(35)外部中断

6.9.1什么是外部中断 (1)内部中断就是指中断源来自于SoC内部&#xff08;一般是内部外设&#xff09;&#xff0c;譬如串口、定时器等部件产生的中断&#xff1b;外部中断是SoC外部的设备&#xff0c;通过外部中断对应的GPIO引脚产生的中断。 (2)按键在SoC中就使用了外部中断…

【每日一题】1498. 满足条件的子序列数目

1498. 满足条件的子序列数目 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数数组 nums 和一个整数 target 。 请你统计并返回 nums 中能满足其最小元素与最大元素的 和 小于或等于 target 的 非空 子序列的数目。 由于答案可能很大&#xff0c;请将结果对 109 7 取余后…

stm32无人机-飞行力学原理

惯性导航&#xff0c;是一种无源导航&#xff0c;不需要向外部辐射或接收信号源&#xff0c;就能自主进行确定自己在什么地方的一种导航方法。 惯性导航主要由惯性器件计算实现&#xff0c;惯性器件包括陀螺仪和加速度计。一般来说&#xff0c;惯性器件与导航物体固连&#xf…

CTFSHOW SSTI

目录 web361 【无过滤】 subprocess.Popen os._wrap_close url_for lipsum cycler web362 【过滤数字】 第一个通过 计算长度来实现 第二个使用脚本输出另一个数字来绕过 使用没有数字的payload web363 【过滤引号】 使用getitem 自定义变量 web364 【过…

数据集笔记:OpenCelliD(手机基站开放数据库)

下载数据的方式可见&#xff1a;【数据获取】全球最大手机基站开源数据库 1 读取数据 import pandas as pdpd.read_csv(C:/Users/16000/Downloads/454.csv/454.csv,headerNone,names[Radio,MCC,MNC,LAC/TAC/NID,CID,Longitude,Latitude,Range,Samples,Changeable1,Changeable…

设计模式6、适配器模式 Adapter

解释说明&#xff1a;将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作 目标接口&#xff08;Target&#xff09;&#xff1a;当前系统所期待的接口&#xff0c;它可以是抽象类或接口 适配者&#xff08;Adaptee&#xff09;&#xff1a…

AIGC(生成式AI)试用 7 -- 桌面小程序

生成式AI&#xff0c;别人用来写作&#xff0c;我先用来写个桌面小程序。 桌面小程序&#xff1a;计算器 需求 Python开发图形界面&#xff0c;标题&#xff1a;计算器 - * / 基本运算计算范围&#xff1a;-999999999 ~ 999999999** 乘方计算&#xff08;例&#xff0c;2*…

LLM之Colossal-LLaMA-2:Colossal-LLaMA-2的简介、安装、使用方法之详细攻略

LLM之Colossal-LLaMA-2&#xff1a;Colossal-LLaMA-2的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年9月25日&#xff0c;Colossal-AI团队推出了开源模型Colossal-LLaMA-2-7B-base。Colossal-LLaMA-2项目的技术细节&#xff0c;主要核心要点总结如下: >> 数据处…

分布式事务-TCC异常-幂等性

1、幂等性问题&#xff1a; 二阶段提交时&#xff0c;如果二阶段执行成功通知TC时出现网路或其他问题中断&#xff0c;那么TC没有收到执行成功的通知&#xff0c;TC内部有定时器不断的重试二阶段方法&#xff0c;导致接口出现幂等性问题。 2、解决方法 和空回滚问题一样也是…

Kotlin只截取Float小数点后数值DecimalFormat

Kotlin只截取Float小数点后数值DecimalFormat import java.text.DecimalFormatfun main(args: Array<String>) {val pi 3.141516Fvar p pi - pi.toInt()println(p)val decimalFormat DecimalFormat("00.0000")val format decimalFormat.format(p)println(…

UE5屏幕适配

一、本程序设计发布在手机上&#xff0c;首先确定屏幕的设计分辨率&#xff0c;这里我们选择iphone6s&#xff0c;750x1334。 二、设置DPI Scale为1.0的比例&#xff0c;点击齿轮标志 因为我们这个程序是手机竖屏使用的&#xff0c;所以DPI Scale Rule选择Shortest Side&#…

c语言常用语法,长时间不用容易忘。

关键字 auto 声明自动变量const 定义常量&#xff0c;如果一个变量被 const 修饰&#xff0c;那么它的值就不能再被改变extern 声明变量或函数是在其它文件或本文件的其他位置定义register 声明寄存器变量signed 声明有符号类型变量或函数static 声明静态变量&#xff0c;修饰…

APA技术架构与说明

1.自动泊车的硬件架构 2.APA自动泊车辅助系统 1&#xff09;APA主要包括以下典型功能 &#xff08;1&#xff09;泊车入库&#xff1a;利用超声波雷达或环视摄像头实现车位识别&#xff0c;并计算出合适行驶轨迹&#xff0c;对车辆进行横向/纵向控制使车辆驶入车位&#xff1…

在MyBatisPlus中添加分页插件

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