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

Linux 消息队列

在Linux中,线程间消息队列可以通过使用System V消息队列或POSIX消息队列来实现。

  1. 使用System V消息队列: System V消息队列是一种基于IPC(Inter-process Communication,进程间通信)的通信机制,可以用于进程或线程间的通信。下面是使用System V消息队列实现线程间通信的步骤:

a. 创建消息队列: 可以使用msgget()函数来创建一个新的消息队列。例如:

key_t key = ftok("path_to_key_file", 'A');
int msgid = msgget(key, IPC_CREAT | 0666);

b. 发送消息: 使用msgsnd()函数向消息队列发送消息。例如:

struct message {
    long mtype;
    char mtext[256];
};

struct message msg;
msg.mtype = 1;
strcpy(msg.mtext, "Hello, world!");

msgsnd(msgid, &msg, sizeof(msg.mtext), 0);

c. 接收消息: 使用msgrcv()函数从消息队列接收消息。例如:

struct message msg;
msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);

printf("Received message: %s\n", msg.mtext);

  1. 使用POSIX消息队列: POSIX消息队列是Linux中提供的另一种消息队列实现方式,它提供了更多的功能和灵活性。下面是使用POSIX消息队列实现线程间通信的步骤:

a. 创建消息队列: 可以使用mq_open()函数创建一个新的消息队列。例如:

mqd_t mq = mq_open("/my_queue", O_CREAT | O_RDWR, 0666, NULL);

b. 发送消息: 使用mq_send()函数向消息队列发送消息。例如:

char msg[] = "Hello, world!";
mq_send(mq, msg, sizeof(msg), 0);

c. 接收消息: 使用mq_receive()函数从消息队列接收消息。例如:

char buf[256];
mq_receive(mq, buf, sizeof(buf), NULL);

printf("Received message: %s\n", buf);

需要注意的是,POSIX消息队列的名称在文件系统中是可见的,可以使用路径名来创建和打开消息队列。

整体实现:

发送到队列中去

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

#define MSGSZ 512
struct  msg_buffer
{
    long   mtype;
    char   mtext[MSGSZ];
    int    age;
    double  many;
}msg_buf;


int main(){
    key_t ftok_key=ftok("./msg1", 'b');
    //创建消息队列
    int msgget_id=msgget(ftok_key, IPC_CREAT|0666);

    //写入队列
    msg_buf.mtype=1;
    msg_buf.age=168;
    msg_buf.many=123.456;
    strcpy(msg_buf.mtext, "“我今天去超市,结果发现超市里没有超市");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf)-sizeof(msg_buf.mtype), 0);
    
    msg_buf.mtype=8;
    strcpy(msg_buf.mtext, "我昨天梦见自己醒来了,结果今天真的醒来了");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat1=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf.mtext), 0);

    msg_buf.mtype=5;
    strcpy(msg_buf.mtext, "我试图在网上搜索‘如何上网’,结果电脑告诉我‘无法连接到互联网’");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat2=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf.mtext), 0);


    return 0;
}

接收

#include <stdio.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <stdlib.h>

#define MSGSZ 512
struct  msg_buffer
{
    long   mtype;
    char   mtext[MSGSZ];
    int    age;
    double  many;
}msg_buf;

int main() {
    // 创建唯一的key
   key_t ftok_key = ftok("./msg1", 'b');

    // 访问消息队列
   int  msgid = msgget(ftok_key, 0666 | IPC_CREAT);
    if (msgid == -1) {
        perror("msgget error");
        exit(1);
    }

    // 接收消息
    //key 接收的大小   读取类型为msgtyp的第一条消息  0: 阻塞接收,直到有消息到达
    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf.mtext), 8, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s\n", msg_buf.mtext);

sleep(1);
    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf)-sizeof(msg_buf.mtype), 1, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s  岁是%d 钱是:%.3fd\n", msg_buf.mtext, msg_buf.age, msg_buf.many);
sleep(1);

    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf.mtext), 5, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s\n", msg_buf.mtext);
sleep(1);

    // 删除消息队列
    if (msgctl(msgid, IPC_RMID, NULL) == -1) {
        perror("msgctl error");
        exit(1);
    }

    return 0;
}


http://www.kler.cn/a/389279.html

相关文章:

  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • Nuxt 版本 2 和 版本 3 的区别
  • 基于混合配准策略的多模态医学图像配准方法研究
  • 前端常用布局模板39套,纯CSS实现布局
  • MyBatis CRUD快速入门
  • 【真题笔记】21年系统架构设计师案例理论点总结
  • go template 模板字符串
  • std::thread线程通知、等待、让渡
  • 绿色能源发展关键:优化风电运维体系
  • 初学Java基础---Day21---正则表达式,日期类,Math类,Random类,System类,Runtime类,大数值运算类,
  • 【cursor添加azure】在cursor中添加azure的openai api
  • 面向对象试题带答案
  • Linux网络管理和修改配置文件
  • HBase 安装与基本操作指南
  • 机器学习与深度学习-1-线性回归从零开始实现
  • MyBatis xml 文件中 SQL 语句的小于号未转义导致报错
  • 高通Quick板上安装编译Ros1 noetic,LeGO_LOAM,FAR_Planner和rslidar_sdk
  • C#里演示使用数学的三角函数
  • 【JavaEE】多线程(1)
  • ssm基于Vue的戏剧推广网站+vue
  • C++ IO流
  • 缺陷的根本原因,出现在代码中的原因可能有哪些?
  • 【架构-37】Spark和Flink
  • rust字符串
  • 如何通过CDN加速提升电商网站双十一购物节用户体验
  • AIGC小红书新赛道,两个平台同时发,操作简单