四.消息队列

目录

1 .消息队列概述

2.消息队列的特点

3.ftok函数

3 创建消息队列-msgget( )

3.1发送消息-msgsnd( )

3.2 接收消息-msgrcv( )

4 消息队列的控制


1 .消息队列概述

       消息队列是一种进程间通信的机制,允许不同进程在系统中传递数据。它们通常由内核维护,并提供了一种异步的通信方式,允许进程通过在队列中发送和接收消息进行通信。

消息队列是消息的链表,存放在内存中,由内核维护

2.消息队列的特点

1、消息队列中的消息是有类型的。

2、消息队列中的消息是有格式的。

3、消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以按消息的类型读取。

4、消息队列允许一个或多个进程向它写入或者读取消息。

5、与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删除。 6、每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。

7、只有内核重启或人工删除消息队列时,该消息队列才会被删除。若不人工删除消息队列,消息队列会一直存在 于系统中。

在 ubuntu 12.04 中消息队列限制值如下:

每个消息内容最多为 8K 字节。

每个消息队列容量最多为 16K 字节 系统中消息队列个数最多为 1609 个。

系统中消息个数最多为 16384 个。

System V 提供的 IPC 通信机制需要一个 key 值,通过 key 值就可在系统内获得一个唯一的消息队列标识符。 key 值可以是人为指定的,也可以通过 ftok 函数获得。

3.ftok函数

ftok函数

ftok()函数是在 Linux/Unix 操作系统中用于创建一个唯一的 key 的函数。

消息队列、信号量等进程间通信方式都需要一个唯一的标识符来标识自己。`ftok()` 函数可以将一个普通文件的路径名和一个整数 ID 转换为一个 key(即 IPC 标识符),返回值为一个 long 类型的 key 值。

ftok()的函数原型为:

#include <sys/types.h> 

#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

 功能:通过文件名和目标值共同创造一个键值并返回值。获得项目相关的唯一的 IPC 键值。

参数:

 pathname:任意一个文件名(文件名或者目录名)路径名

 proj_id:目标值,范围一般是0~127,项目 ID,非 0 整数(只有低 8 位有效)。

返回值: 成功:返回 key 的键值。 失败:‐1

 如果使用ftok函数获取键值,得到的键值是由ftok的第一个 参数对应文件的信息和第二个参数一起决定的。

其中,参数 `pathname` 是指文件的路径名,`proj_id` 是一个用户自定义的整数 ID。

`ftok()` 函数会根据给定的文件路径名和整数 ID 生成一个唯一的 key。在多个进程中使用同一个 key 可以让它们访问同一个 IPC 对象,例如同一个消息队列或同一个信号量集合。

需要注意的是,如果文件不存在或者无法访问,或者多个进程使用不同的文件路径名和/或整数 ID 调用 `ftok()` 生成相同的 key,则可能导致 IPC 系统中的冲突。因此,在使用 `ftok()` 函数时需要选择一个合适的文件路径名和整数 ID,并确保所有进程都使用相同的参数来调用该函数。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值//只要保证ftok的第一个参数对应的文件和第二个参数值相同,则不管程序运行多少遍或者多少个进程或者键值//键值一定都是唯一的key_t mykey;if((mykey = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}printf("key = %#x\n", mykey);return 0;
}

3 创建消息队列-msgget( )

man msgget

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgget(key_t key, int msgflg);

功能:创建一个消息队列,并得到该消息队列的id

 参数:

 key:键值,唯一的键值确定唯一的消息队列

 方法1:任意指定一个数

方法2:使用ftok函数获取键值

 msgflg:消息队列的访问权限

 一般设置为 IPC_CREAT | IPC_EXCL | 0777 或者 IPC_CREAT | 0777。

 返回值:

 成功:消息队列的id  失败:‐1

使用shell命令操作消息队列:

查看消息队列 : ipcs ‐q  

删除消息队列 : ipcrm ‐q msqid 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int main(int argc, char const *argv[])
{//通过ftok函数获取ipc键值key_t mykey;if((mykey = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}printf("mykey = %#x\n", mykey);//通过msgget函数创建一个消息队列int msqid;if((msqid = msgget(mykey, IPC_CREAT | 0666)) == -1){perror("fail to msgget");exit(1);}printf("msqid = %d\n", msqid);system("ipcs -q");return 0;
}

3.1发送消息-msgsnd( )

man msgsnd

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

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

功能:向指定的消息队列发送数据(写操作)

 参数:

 msqid:消息队列的id

 msgp:要写入的数据,需要自己定义结构体

struct struct_name{

 long mtype; //消息的编号,必须大于0

 char mtext[128]; //消息正文,可以定义多个成员

 }

msgsz:消息正文的大小,不包括消息的编号长度

msgflg:标志位

 0 阻塞

 IPC_NOWAIT 非阻塞

返回值:

 成功:0

失败:‐1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define N 128typedef struct{long msg_type; //消息类型,必须在结构体的第一个位置并且类型必须是longchar msg_text[N]; //消息正文,也可以有多个成员并且类型也可以是任意
}MSG;#define MSGTEXT_SIZE (sizeof(MSG) - sizeof(long))//此处表示消息正文的大小int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t key;if((key = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}//使用msgget函数创建一个消息队列int msgid;if((msgid = msgget(key, IPC_CREAT | 0777)) == -1){perror("fail to msgget");exit(1);}system("ipcs -q");//使用msgsnd函数向消息队列中发送数据(写操作)MSG msg1 = {1, "hello world"};MSG msg2 = {2, "nihao beijing"};MSG msg3 = {2, "hello kitty"};MSG msg4 = {3, "welcome to china"};if(msgsnd(msgid, &msg1, MSGTEXT_SIZE, 0) == -1){perror("fail to msgsnd");exit(1);}if(msgsnd(msgid, &msg2, MSGTEXT_SIZE, 0) == -1){perror("fail to msgsnd");exit(1);}if(msgsnd(msgid, &msg3, MSGTEXT_SIZE, 0) == -1){perror("fail to msgsnd");exit(1);}if(msgsnd(msgid, &msg4, MSGTEXT_SIZE, 0) == -1){perror("fail to msgsnd");exit(1);}system("ipcs -q");return 0;
}

3.2 接收消息-msgrcv( )

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

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

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

 功能:从消息队列中接收数据(读操作),接收的数据会从消息队列中删除

 参数:

 msqid:消息队列id

 msgp:保存接收到的数据的结构体

 struct struct_name{

 long mtype; //消息的编号,必须大于0

 char mtext[128]; //消息正文,可以定义多个成员

 }

msgsz:消息正文的大小

 msgtyp:设置要接收哪个消息

 msgtyp = 0 按照写入消息队列的顺序依次读取

 msgtyp > 0 只读取消息队列中消息编号为当前参数的第一个消息

msgtyp < 0 只读取消息队列中小于等于当前参数的绝对中内最小的第一个消息

 msgflg:标志位

 0 阻塞

 IPC_NOWAIT 非阻塞

 返回值:

 成功:接收到的消息正文的长度

 失败:‐1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define N 128typedef struct{long msg_type;char msg_text[N];
}MSG;#define MSGTEXT_SIZE (sizeof(MSG) - sizeof(long))int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t key;if((key = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}//使用msgget函数创建一个消息队列int msgid;if((msgid = msgget(key, IPC_CREAT | 0777)) == -1){perror("fail to msgget");exit(1);}system("ipcs -q");//通过msgrcv函数接收消息队列中的信息(读操作)//注意:如果没有第四个参数指定的消息时,msgrcv函数会阻塞等待MSG msg;//如果第四个参数为0,则按照先进先出的方式读取数据//if(msgrcv(msgid, &msg, MSGTEXT_SIZE, 0, 0) == -1) //如果第四个参数为>0,则获取当前值得消息类型的数据//if(msgrcv(msgid, &msg, MSGTEXT_SIZE, 2, 0) == -1)//如果第四个参数为<0,则获取当前值得绝对值内消息类型最小的数据if(msgrcv(msgid, &msg, MSGTEXT_SIZE, -3, 0) == -1){perror("fail to msgrcv");exit(1);}printf("recv_msg = %s\n", msg.msg_text);system("ipcs -q");return 0;
}

4 消息队列的控制

man msgctl

     #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>

       int msgctl(int msqid, int cmd, struct msqid_ds *buf);

功能:设置或者获取消息队列的信息

 参数:

msqid:指定的消息队列的id

 cmd:具体操作的指令

 IPC_SET :设置属性

 IPC_STAT: 获取属性

 IPC_RMID: 删除消息队列

msqid_ds:设置或者获取消息队列的属性

 返回值:

 成功:0  失败:‐1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值key_t key;if((key = ftok(".", 100)) == -1){perror("fail to ftok");exit(1);}//使用msgget函数创建一个消息队列int msgid;if((msgid = msgget(key, IPC_CREAT | 0777)) == -1){perror("fail to msgget");exit(1);}printf("msgid = %d\n", msgid);system("ipcs -q");//通过msgctl函数删除消息队列if(msgctl(msgid, IPC_RMID, NULL) == -1){perror("fail to msgctl");exit(1);}system("ipcs -q");return 0;
}

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

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

相关文章

PEGASUS模型介绍

PEGASUS介绍 概述 模型论文为Pre-training with Extracted Gap-sentences for Abstractive Summarization&#xff0c;简称为PEGASUS。面向的情况主要是因为目前预训练语言任务主要为MLM和NSP任务&#xff0c;即为掩码预测任务和下一句预测任务&#xff0c;没有面向生成式文本…

普中STM32-PZ6806L开发板(HAL库函数实现-USART1 printf+scanf/gets)

简介 实现printfscanf/gets通过USART1 的发送接收。 电路原理图 板载USB CH340串口电路原理图主芯片串口引脚图 我的板子板子自带串口坏掉了, 所以使用USB转TTL线, 连接如下 电路原理图 实物图 其他知识 scanf是以空白符(空格、制表符、换行等等)为结束标志的,当遇到空白符…

Unity坦克大战开发全流程——开始场景——开始界面

开始场景——开始界面 step1&#xff1a;设置UI 反正按照这张图拼就行了 step2&#xff1a;写脚本 前面的拼UI都是些比较机械化的工作&#xff0c;直到这里写代码的时候才真正开始有点意思了&#xff0c;从这里开始&#xff0c;我们就要利用面向对象的思路来进行分析&#xff1…

AJAX:整理3:原生AJAX的相关操作

注意AJAX的步骤 // 1.创建对象 const xhr new XMLHttpRequest()// 2.初始化 设置 请求方法 和 url xhr.open("GET", "http://localhost:9090/server")// 3.发送 xhr.send()// 4.事件绑定 处理服务端返回的结果 // readyState 是xhr对象中的属性&#xff…

超维空间S2无人机使用说明书——51、基础版——使用yolov8进行目标跟踪

引言&#xff1a;为了提高yolo识别的质量&#xff0c;提高了yolo的版本&#xff0c;改用yolov8进行物体识别&#xff0c;同时系统兼容了低版本的yolo&#xff0c;包括基于C的yolov3和yolov4&#xff0c;以及yolov7。 简介&#xff0c;为了提高识别速度&#xff0c;系统采用了G…

Vue小练习--任务列表

这是一个非常实用的例子&#xff0c;主要实用的是v-model、v-on、v-for指令&#xff0c;javaScript的数组也会涉及一些&#xff0c;javaScript数组方法有很多&#xff0c;本文使用的添加元素和删除元素非常实用&#xff0c;可以记下来。 设计思路 很多例子看起来很难&#xf…

使用Google OSV工具扫描依赖安全漏洞

安全漏洞是软件工程化能力的试金石 2021年年底&#xff0c;Log4j的漏洞陆续被公开。因为该框架被大量的开源软件依赖&#xff0c;所以&#xff0c;漏洞影响面非常大。 面对这个漏洞&#xff0c;我们遇到的第一个问题是&#xff1a;如何知道我们哪些工程使用了Log4j&#xff1f;…

用python画最简单的图案,用python画小猫简单代码

本篇文章给大家谈谈用python画小猫简单100行代码&#xff0c;以及用python画最简单的图案&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 Source code download: 本文相关源码 from turtle import * #两个函数用于画心 defcurvemove():for i in range(200): …

电池充电器、监控器和控制器AD7284WBSWZ、LT8490EUKJ、LTC4162EUFD-FAD、LTC4162IUFD-LAD【电源管理】

1、AD7284WBSWZ 8通道锂离子电池监控系统 IC 64LQFP AD7284 8通道锂离子电池监控系统包括对堆叠式锂离子电池进行通用监控所需的全部功能。AD7284具有支持四到八个电池管理单元的多路复用单元电压和辅助模数转换器 (ADC) 测量通道。设计人员可以使用四个辅助ADC输入通道进行温…

lag-llama源码解读(Lag-Llama: Towards Foundation Models for Time Series Forecasting)

Lag-Llama: Towards Foundation Models for Time Series Forecasting 文章内容&#xff1a; 时间序列预测任务&#xff0c;单变量预测单变量&#xff0c;基于Llama大模型&#xff0c;在zero-shot场景下模型表现优异。创新点&#xff0c;引入滞后特征作为协变量来进行预测。 获得…

Power Apps 学习笔记 - IOrganizationService Interface

文章目录 1. IOrganization Interface1.1 基本介绍1.2 方法分析 2. Entity对象2.1 Constructor2.2 Properties2.3 Methods 3. 相关方法3.1 单行查询 Retrive3.2 多行查询 RetriveMultiple3.3 增加 Create3.4 删除 Delete3.5 修改 Update 1. IOrganization Interface 1.1 基本介…

rax3000m刷openwrt固件

rax3000m刷机过程&#xff08;nand版本&#xff09; 刷机准备文件https://www.123pan.com/s/X5m9-6Ynj.html提取码:VtBW 接线关系&#xff1a;路由器lan口接电脑 1.上传配置开启ssh的配置文件&#xff08;登录路由器后台管理界面在找到配置管理&#xff0c;上传配置文件rax3…

[NCTF 2022] web题解

[NCTF 2022]calc 考点&#xff1a;python环境变量注入 打开题目&#xff0c;F12有hint 访问一下得到源码 app.route("/calc",methods[GET]) def calc():ip request.remote_addrnum request.values.get("num")log "echo {0} {1} {2}> ./tmp/log…

【Unity美术】Unity工程师对3D模型需要达到的了解【一】

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

后端程序员React初接触1

后端程序员React初接触 学习react基础与相关库的使用学习 包括react基础 路由 组件库等等 react是用于构建用户界面的JavaScript库 发送请求获取数据处理数据操作dom呈现页面&#xff08;react帮忙操作dom&#xff09; 数据渲染为视图 有facebook打造并开源 解决的问题 dom操…

集群部署篇--Redis 哨兵模式

文章目录 前言一、哨兵模式介绍&#xff1a;1.1 介绍&#xff1a;1.2 工作机制&#xff1a; 二、哨兵模式搭建&#xff1a;2. 1 redis 主从搭建&#xff1a;2.2 setinel 集群搭建&#xff1a;2.2.1 配置&#xff1a; sentinel.conf &#xff1a;2.2.2 运行容器&#xff1a;2.2.…

jQuery日历签到插件下载

jQuery日历签到插件下载-遇见你与你分享

【MySQL】数据库之存储过程(“SQL语句的脚本“)

目录 一、什么是存储过程&#xff1f; 二、存储过程的作用 三、如何创建、调用、查看、删除、修改存储过程 四、存储过程的参数&#xff08;输入参数&#xff0c;输出参数&#xff0c;输入输出参数&#xff09; 第一种&#xff1a;输入参数 第二种&#xff1a;输出参数 …

Leetcode算法系列| 10. 正则表达式匹配

目录 1.题目2.题解C# 解法一&#xff1a;分段匹配法C# 解法二&#xff1a;回溯法C# 解法三&#xff1a;动态规划 1.题目 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 1.‘.’ 匹配任意单个字符 2.‘.’ 匹配任意单个字…

【DevOps 工具链】日志管理工具 - 22种 选型(读这一篇就够了)

文章目录 1、简述2、内容分类3、归纳对比表&#xff08;排序不分先后&#xff09;4、日志管理主要目的5、日志管理工具 22种 详细&#xff08;排序不分先后&#xff09;5.1、ManageEngine EventLog Analyzer5.1.1、简介5.1.2、效果图5.1.3、日志管理架构5.1.4、EventLog Analyz…