【并发程序设计】14.消息队列

14.消息队列

消息队列(Message Queue)是一种通信机制,用于在分布式系统中传递和管理消息的队列型数据结构

  • 消息队列通常是一个先进先出(FIFO)的数据结构,它允许多个进程或线程之间以异步方式进行通信。
  • 它可以被看作是一个系统内核中的内部链表,其中发送进程将消息添加到队列中,接收进程从队列中读取消息进行处理。
  • 这种通信机制传递的数据通常是结构化的,而不是简单的字节流。

在这里插入图片描述

消息队列使用步骤

  • 发送端:
    1. 申请Key ftok
    2. 打开/创建消息队列 msgget
    3. 向消息队列发送消息 msgsnd
  • 接收端:
    1. 打开/创建消息队列 msgget
    2. 从消息队列接收消息 msgrcv
    3. 控制(删除)消息队列 msgctl

发送端

1.申请Key

ftok函数

  1. 原型key_t ftok(const char *pathname, int proj_id);
  2. 功能:生成一个唯一的键值,通常用于创建共享内存或消息队列等
  3. 参数
    • pathname:一个已经存在的文件路径,通常是程序中已经打开的文件。
    • proj_id:一个整数,用于与pathname组合生成唯一的键值。
  4. 返回值
    • 成功,返回一个key_t类型的键值,用于后续的系统调用(如shmget、msgget等)
    • 失败,返回-1

2.打开/创建消息队列

msgget函数

  1. 原型int msgget(key_t key, int msgflg);
  2. 功能:创建或打开一个消息队列
  3. 参数
    • key:一个唯一的键值,通常由ftok函数生成。
    • msgflg:消息队列的访问权限和创建标志,IPC_CREAT、IPC_EXCL、IPC_NOWAIT等
      1. IPC_CREAT
        • 若消息队列不存在,则创建一个新的消息队列。
      2. IPC_EXCL
        • 当与 IPC_CREAT 同时使用时,如果已经存在与 key 相关联的消息队列,msgget 会失败并返回 -1。
        • 如果没有同时指定 IPC_CREATIPC_EXCL 将被忽略。
      3. IPC_NOWAIT
        • 如果消息队列不能立即创建(例如,由于资源限制),msgget 会立即返回 -1,而不是等待直到可以创建为止。
        • 如果没有指定 IPC_NOWAIT,系统会等待直到可以创建消息队列为止。
      4. IPC_PRIVATE
        • 在 Linux 中,IPC_PRIVATE 是一种特殊的键值,它允许不使用 ftok 来生成唯一的 key
        • 使用 IPC_PRIVATE 作为 key 时,系统会为调用者分配一个私有的、唯一的消息队列标识符。
      5. IPC_RMID
        • 这是一个较新的选项,用于删除所有关联的消息队列,而不仅仅是与给定 key 关联的那个。
      6. 06660777 等权限位
        • 这些数字代表消息队列的访问权限。通常,它们被设置为八进制数,其中每个数字对应于用户、组和其他人的读/写权限。
  4. 返回值
    • 成功,返回消息队列的标识符(非负整数)
    • 失败,返回-1
  5. 向消息队列发送消息 msgsnd函数
    1. 原型int msgsnd(int msqid, const struct msgbuf *msgp, int msgsz, int msgflg);
    2. 功能:向消息队列发送一个消息
    3. 参数
      • msqid:消息队列的标识符,通常由msgget函数返回。
      • msgp:指向要发送的消息结构的指针,该结构包含消息类型和消息正文。
      • msgsz:消息的大小(以字节为单位)。
      • msgflg:指定消息发送的标志,可以是IPC_NOWAIT等,同msgget函数中的msgflg参数。
    4. 返回值
      • 成功,返回0
      • 失败,返回-1

示例

发送一条消息到队列

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

typedef struct // 定义一个结构体类型
{
    long msg_type; // 消息类型,必须是long型
    char buf[128]; // 消息内容缓冲区,用于存储消息内容
}msgT;    

#define MSGLEN  (sizeof(msgT)-sizeof(long)) // 定义消息长度宏,减去长整型变量的大小

int main() // 主函数
{
    key_t key; // 定义一个key_t类型的变量key,用于存储生成的键值
    int msgid; // 定义一个整型变量msgid,用于存储消息队列的标识符
    int ret;   // 定义一个整型变量ret,用于存储函数调用的返回值
    msgT msg;  // 定义一个msgT类型的结构体变量msg,用于存储要发送的消息
    
	//1.生成一个键值
    key = ftok(".",100); // "."表示当前目录,100是一个任意的整数
    if(key<0) // 如果生成键值失败
    {
        perror("ftok"); // 打印错误信息并返回0
        return 0;
    }
    
    //2.函数创建
    msgid = msgget(key,IPC_CREAT|0666); // key为键值,IPC_CREAT表示如果不存在则创建,0666表示权限设置为可读写
    if(msgid<0) // 如果获取消息队列失败
    {
        perror("msgget"); // 打印错误信息并返回0
        return 0;
    }
	
    //3.发送消息
    msg.msg_type = 1; // 设置消息类型为1
    strcpy(msg.buf,"this msg type 1"); // 将消息内容复制到buf中
    ret = msgsnd(msgid,&msg,MSGLEN,0);//0表示不等待
    if(ret<0) // 如果发送消息失败
    {
        perror("msgsnd"); // 打印错误信息并返回0
        return 0;
    }
}

运行程序后,在终端输入ipcs -qc查看消息队列

在这里插入图片描述

这就是刚刚发送到消息队列的信息

接收端

  1. 打开/创建消息队列 msgget函数(发送端用过)

从消息队列接收消息

msgrcv函数

  1. 原型ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
  2. 功能:从消息队列中接收一个消息
  3. 参数
    • msqid:消息队列的标识符,通常由msgget函数返回。
    • msgp:指向要接收的消息结构的指针,该结构包含消息类型和消息正文。
    • msgsz:消息的大小(以字节为单位)。
    • msgtyp指定要接收的消息类型
      • msgtyp=0:收到的第一条消息,任意类型。
      • msgtyp>0:收到的第一条 msg_typ类型的消息。
      • msgtyp<0:接收类型等于或者小于msgtyp绝对值的第一个消息。
    • msgflg
      • 0:阻塞式接收消息
      • IPC_NOWAIT:如果没有返回条件的消息调用立即返回,此时错误码为ENOMSG
      • MSG_EXCEPT:与msgtyp配合使用返回队列中第一个类型不为msgtyp的消息
  4. 返回值
    • 成功时返回实际接收到的消息大小(以字节为单位)
    • 失败时返回-1
  5. 控制(删除)消息队列 msgctl函数
    1. 原型int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    2. 功能:控制消息队列,包括获取和设置消息队列的属性
    3. 参数
      • msqid:消息队列的标识符,通常由msgget函数返回。
      • cmd:指定要执行的命令,可以是IPC_STATIPC_SET等。
      • buf:指向一个msqid_ds结构体的指针,用于存储或设置消息队列的属性。
    4. 返回值
      • 成功时返回0
      • 失败时返回-1

示例

接收消息队列的一条消息

#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; // 消息队列ID
  key_t key; // 消息队列关键字
  msgT msg; // 消息结构体实例
  int ret; // 返回值
  key = ftok(".",100); // 生成消息队列关键字
  if(key<0)
  {
      perror("ftok"); // 如果生成失败,打印错误信息
      return 0;
  }

  // 1.创建或获取消息队列ID
  msgid = msgget(key,IPC_CREAT|0666); 
  if(msgid<0)
  {
      perror("msgget"); // 如果获取失败,打印错误信息
      return 0;
  }

  // 2.从消息队列中接收消息
  ret = msgrcv(msgid,&msg,MSGLEN,0,0); 
  if(ret<0)
  {
      perror("msgrcv"); // 如果接收失败,打印错误信息
      return 0;
  }

  printf("receiv msg type=%d,buf=%s\n",(int)msg.msg_type,msg.buf); // 打印接收到的消息类型和内容

   // 3.删除消息队列
  ret = msgctl(msgid,IPC_RMID,NULL);
  if(ret<0)
  {
      perror("msgctl"); // 如果删除失败,打印错误信息
      return 0;
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Google力作 | Infini-attention无限长序列处理Transformer

更多文章&#xff0c;请关注微信公众号&#xff1a;NLP分享汇 原文链接&#xff1a;Google力作 | Infini-attention无限长序列处理Transformerhttps://mp.weixin.qq.com/s?__bizMzU1ODk1NDUzMw&mid2247485000&idx1&sne44a7256bcb178df0d2cc9b33c6882a1&chksm…

OpenCV 的几种查找图像中轮廓边缘的方法

原始图片&#xff1a; 1、Sobel() Sobel 算子结合了高斯平滑和微分&#xff0c;用于计算图像的梯度&#xff0c;从而突出显示边缘。 import cv2# 读取图像 image cv2.imread(image.png, cv2.IMREAD_GRAYSCALE)# 使用 Sobel 算子查找水平和垂直边缘 sobel_x cv2.Sobel(image…

浅谈旧项目如何添加新依赖

Spring项目创建之后&#xff0c;还想添加新的依赖&#xff08;如Spring框架内置的依赖&#xff09;&#xff0c;可以安装插件&#xff1a; 装完该插件之后&#xff0c;就可以在pom.xml文件里&#xff0c;右键选择 Generate即可出现下述界面&#xff1a; 点击ok即可添加新的…

服务器硬件基础知识学习

服务器硬件基础知识涵盖了从CPU到存储&#xff0c;再到网络连接和总线技术等关键组件。 1. 处理器 - 两大流派&#xff1a;我们常用的处理器主要分为Intel和AMD两大阵营。Intel的Xeon系列和AMD的EPYC系列都是专为服务器设计的&#xff0c;它们支持多核处理&#xff0c;能够应对…

最新一站式AI创作中文系统网站源码+系统部署+支持GPT对话、Midjourney绘画、Suno音乐、GPT-4o文档分析等大模型

一、系统简介 本文将介绍最新的一站式AI创作中文系统&#xff08;集成ChatGPTMidjourneySunoStable Diffusion&#xff09;——星河易创AI系统&#xff0c;该系统基于ChatGPT的核心技术&#xff0c;融合了自然语言问答、绘画、音乐、文档分享、图片识别等创作功能&#xff0c;…

统信UOS桌面操作系统1070上使用notepad--文本编辑器

原文链接&#xff1a;统信UOS桌面操作系统1070上使用notepad–文本编辑器 Hello&#xff0c;大家好啊&#xff01;今天我要向大家推荐一款在统信UOS桌面操作系统1070上非常好用的文本编辑器软件——“notepad–”。这款软件功能强大、操作简便&#xff0c;特别适合开发人员和日…

enum4linux一键查询SMB信息(KALI工具系列十六)

目录 1、KALI LINUX简介 2、enum4linux工具简介 3、在KALI中使用enum4linux 3.1 目标主机IP&#xff08;win&#xff09; ​编辑 3.2 KALI的IP 4、操作示例 4.1 运行工具 4.2 列出用户名 4.3 提取用户名 4.4 使用自定义RID范围 4.5 列出组 4.6 列出共享文件夹 4.7…

自动评论自动私信引流系统,自动化时代的挑战与机遇

随着科技的飞速发展&#xff0c;自动化技术已经渗透到我们生活的方方面面。从工业生产线上的机械臂到家庭中的智能助手&#xff0c;自动化不仅改变了我们的工作方式&#xff0c;也在重塑着社会的面貌。然而&#xff0c;在享受自动化带来的便利和效率的同时&#xff0c;我们也必…

时间序列的谱分解pt.2

16.dvi (berkeley.edu)https://www.stat.berkeley.edu/~bartlett/courses/153-fall2010/lectures/16.pdfpt1 时间序列的谱分解-CSDN博客

Linux--Socket编程基础

一、Socket简介 套接字&#xff08; socket &#xff09;是 Linux 下的一种进程间通信机制&#xff08; socket IPC &#xff09;&#xff0c; 使用 socket IPC 可以使得在不同主机上的应用程序之间进行通信&#xff08;网络通信&#xff09;&#xff0c;当然也可以是同一台…

深度学习之加宽全连接

1.Functional API 搭建神经网络模型 1.1.利用Functional API编写宽深神经网络模型进行手写数字识别 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_iris from sklearn.model_selection import train_test_spli…

【免费Web系列】JavaWeb实战项目案例三

这是Web第一天的课程大家可以传送过去学习 http://t.csdnimg.cn/K547r 部门管理开发 1. 删除部门 1.1 需求分析 删除部门数据。在点击 "删除" 按钮&#xff0c;会根据ID删除部门数据。 了解了需求之后&#xff0c;我们再看看接口文档中&#xff0c;关于删除部门…

还没搞懂作用域、执行上下文、变量提升?看这篇就够啦

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 目录 作用域&#xff08;Scope&#xff09; 全局作用域 函数作用域 块级作用域…

编译选项导致的结构体字节参数异常

文章目录 前言问题描述原因分析问题解决总结 前言 在构建编译工程时&#xff0c;会有一些对应的编译配置选项&#xff0c;不同的编译器&#xff0c;会有对应的配置项。本文介绍GHS工程中编译选项配置不对应导致的异常。 问题描述 在S32K3集成工程中&#xff0c;核1的INP_SWC…

【并发程序设计】15.信号灯(信号量)

15.信号灯(信号量) Linux中的信号灯即信号量是一种用于进程间同步或互斥的机制&#xff0c;它主要用于控制对共享资源的访问。 在Linux系统中&#xff0c;信号灯作为一种进程间通信&#xff08;IPC&#xff09;的方式&#xff0c;与其他如管道、FIFO或共享内存等IPC方式不同&…

c++ 哈希 unordered_map unordered_set 的学习

1. unordered 系列 在 c98 中&#xff0c; STL 提供了底层是红黑树结构的一系列关联式容器&#xff0c;set 和 map 的查询效率可以达到 log2N&#xff0c;红黑树最差的情况也只是需要比较红黑树的高度次&#xff0c;当节点数量非常多时&#xff0c;查找一个节点还需要比较几十…

护肤品美妆商城小程序的作用是什么

经营美妆的方式多种多样&#xff0c;商场街边、电商平台、微商等&#xff0c;无论厂商品牌还是经销商批发零售都有大量目标群体&#xff0c;客户在哪里商家就应该在哪里&#xff0c;私域生意模式&#xff0c;商家需要线上多渠道获客转化和提高营收。 运用【雨科】平台搭建护肤…

PatchEmbed

PatchEmbed 是用于计算机视觉任务的神经网络层&#xff0c;特别是在Vision Transformer (ViT) 模型中使用。它负责将输入的图像分割成固定大小的图像块&#xff08;patches&#xff09;&#xff0c;并将这些图像块线性嵌入到高维空间中。这是Vision Transformer处理图像的方式&…

JVM虚拟机性能监控工具

命令行工具 jps 虚拟机进程状况查询工具 jps(JVM Process Status Tool)&#xff0c;可以列出正在运行的虚拟机进程&#xff0c;并显示虚拟机执行主类名称或者jar文件名&#xff0c;还有这些进程的本地虚拟机唯一ID(LVMID&#xff0c;Local Virtual Machine Identifier)。 # …

Vue.js 与 TypeScript(1) :项目配置、props标注类型、emits标注类型

像 TypeScript 这样的类型系统可以在编译时通过静态分析检测出很多常见错误。这减少了生产环境中的运行时错误&#xff0c;也让我们在重构大型项目的时候更有信心。通过 IDE 中基于类型的自动补全&#xff0c;TypeScript 还改善了开发体验和效率。 一、项目配置 在使用 npm cr…