当前位置: 首页 > news >正文

系统编程-消息队列

消息队列

目录

消息队列

引入

一、消息队列的特点

二、使用指令查看消息队列

三、使用消息队列进行通信的步骤

1、获取键值

2、创建或获取消息队列 id

3、使用消息队列进行数据的传输

4、msgrcv -- 从消息队列中读取数据

5、消息队列的多种操作函数


引入

-- 进程间通信 (IPC)是指在不同进程之间传播或交换信息。IPC的方式通常有管道(包括无名管道和命名管道)、消息队列、信号量、共享存储、Socket、Streams等。

-- 这章讲消息队列

  • 相当于系统级别的链表(系统开着,消息队列在。系统关,消息队列关)-- 所有进程都可使用

  • 多个进程间进行数据传输           -- 消息队列

一、消息队列的特点

-- 类似于管道

  • (1)先进先出,数据读出来会从消息队列中消失。

  • (2)要进行消息的读取,必须有消息否则会读阻塞。

  • (3)消息队列满了,会产生写阻塞。

  • (4)有消息类型之分,用来确定读取的消息类型

-- 消息队列可以解决的问题:多个进程间进行数据的传输

二、使用指令查看消息队列

-- 指令:ipcs

  • ipas可以查看系统下的system V的状态 

    alt text

-- 指令:ipcs -q 只查看消息队列 

alt text

-- 消息队列的相关信息:

  • 键值:获取消息队列 id 的唯一标识符,一个键值对应一个消息队列的 id,是八位的十六进制,例如 0x12345678

  • msqid:用于区分不同的消息队列 也代表该消息队列的号(id)

  • 拥有者:谁创建的

  • 权限:对该消息队列的操作权限
    例:666 可读可写

  • 已用字节数:消息队列中一共存放了多少个字节的信息

  • 消息:存放了消息的个数


三、使用消息队列进行通信的步骤

alt text

1、获取键值

(1)函数获取:

-- 函数头文件

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

-- 函数原型

  • key_t ftok(const char *pathname, int proj_id)

-- 函数的作用:

  • 通过传入的参数来获取指定的键值(ftok的两个参数一样,获取的键值就一样)

-- 函数的参数:

  • pathname:必须是存在的路径
  • proj_id:0~255

-- 函数的返回值:

  • 会根据函数的参数来返回一个键值

alt text

(2)自己定义:

  • #define my_key 0x12345678

-- 键值的作用:

  • 一样的键值可以让不同进程来获取到同一个消息队列的id号
  • 一个键值对应一个id号,是一一对应的。具有唯一性。

2、创建或获取消息队列 id

-- 函数头文件

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

-- 函数原型

  • int msgget(key_t key, int msgflg)

-- 函数的作用:

  • 创建或获取消息队列的 id 用于进程间通信

-- 函数的参数:

  • key:键值 相同的键值可以获取相同的消息队列 id
  • msgflg:固定填写    IPC_CREAT|0666

-- 函数的返回值:

  • 成功返回 消息队列的 id >= 0
  • 失败返回 -1

alt text

alt text

3、使用消息队列进行数据的传输

-- 收发的数据类型必须为结构体

-- 函数的头文件

  • #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:要将消息发送到哪一个消息队列中去

  • msgsz:填写 mtext 的大小 ,填写:第二个参数的结构体大小 - 8

  • msgflg:填0是阻塞发送,如果消息队列空间不够,会阻塞,直到有空间可以进行写入
    -- IPC_NOWAIT 非阻塞发送

  • msgp:发送的消息的首地址

-- 这里必须要用结构体 需要自己在程序中定义(发送和接收的结构体必须定义的一模一样)

struct msgbuf {long mtype;/* message type, must be > 0 */char mtext[1];/* message data */xxxx;.....;
};

-- 结构体中的第一个成员必须为 long 类型,赋值时必须给大于 0 的值

-- 函数的返回值:

  • 成功返回 0
  • 失败返回 -1
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>#define key 0x12345678struct student
{long mtype;  -- 第一个数据类型必须是long型int id;char name[20];
};int main()
{//key_t  key = ftok("/home/pimouren/learn", 55);printf("%x\n",key);int id = msgget(key,IPC_CREAT|0666);if(id == -1){perror("msgget");return -1;}printf("id = %d\n",id);struct student stu;printf("请输入学生的学号!\n");scanf("%d",&stu.id);printf("请输入学生的名字!\n");scanf("%s",stu.name);int  mm = msgsnd(id, &stu,sizeof(stu)-8, 0);if(mm == -1){perror("msgsnd");return -1;}return 0;
}

alt text

-- 再次向消息队列中写入数据,已用字节数发生改变

alt text

4、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);

-- 函数的作用:

  • 从消息队列中进行数据的读取

-- 函数的参数:

  • msqid:要从哪一个消息队列读取消息
  • msgp:读取到的消息保存的首地址
  • msgsz:要读取的消息字节数,填写结构体大小 - 8
  • msgtyp:要接受的消息类型

"> 0"
-- 接收指定的消息类型中的第一条消息
"0"
-- 接收消息队列中的第一条消息
"<0"
-- 接收小于 msgtyp 绝对值的消息类型
例如 填写-3, |-3| == 3 ,那么可以读取 1 或2 的消息类型

  • msgflg: 0 阻塞接收 如果没有 msgtyp 指定消息类型会一直阻塞 直到有该消息类型来到 IPC_NOWAIT 非阻塞

-- 函数的返回值:

  • 成功返回 实际读取到的字节数
  • 失败返回 -1

alt text

alt text

alt text

5、消息队列的多种操作函数

-- 函数头文件

  • #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_STAT 获取消息队列的信息
IPC_SET 更改消息队列的设置
IPC_RMID 删除消息队列
当 cmd 为 IPC_RMID 时 第三个参数给 NULL buf:结构体指针 用于传出和设置消息队列属性

-- 函数的返回值:

  • 成功 返回 0
  • 失败 返回 -1

-- 这个函数主要用来删除消息队列

alt text

-- 使用指令删除消息队列

  • 指令:ipcrm -q msgid

alt text


http://www.mrgr.cn/news/12794.html

相关文章:

  • 【STM32】FSMC
  • leetcode 560 和为k 的子数组
  • spring整合redis(常用数据类型操作)
  • [英语单词] quorum
  • 呼入的电话通过http接口转接(mod_cti基于FreeSWITCH)
  • 实现通用人工智能 (AGI) 面临的挑战
  • “北京地铁系统中人脸识别技术的安全与效率问题研究”
  • LLVM-MLIR 学习记录
  • 如何使用ssm实现视频点播系统设计与实现+vue
  • 利用Aspose.BarCode 在 C# 中创建微型二维码
  • 微软Win11 24H2最新可选更新补丁26100.1591发布!
  • 记录一次给iOS 工程添加.gitignore文件
  • 利用Nginx反向代理优化Web应用的性能与安全
  • [Jsprit]Jsprit学习笔记-初见Jsprit-doc
  • 绿色守望者:虫情测报仪助力现代农业绿色发展
  • 积鼎科技携手潍柴动力的喷嘴雾化模拟项目荣获2024年数字仿真卓越应用奖
  • OpenCV入门12.1:角点和特征点概述
  • 关于自定义控件,头文件找不到问题的解决办法
  • 低代码集成中心:简化复杂流程的智能解决方案
  • C语言迷宫制造