Java进程间通信之消息队列

目录
  • 消息队列
    • 1.消息队列的原理
    • 2.消息队列的接口:
      • 2.1创建消息队列
      • 2.2向消息队列发送消息
      • 2.3接收消息:
      • 2.4操作消息队列的接口
      • 2.5代码测试:
  • 信号量:
    • 信号量的原理
  • 总结

消息队列

1.消息队列的原理

  • 1.1 msgqueue采用链表来实现消息队列, 该链表是由系统内核维护,
  • 1.2 系统中可能有很多的msgqueue, 每个MQ用消息队列描述符(消息队列ID: qid) 来区分,qid是唯一 的,用来区分不同的MQ。
  • 1.3在进行进程间通信时,一个进程将消息加到MQ尾端,另一个进程从消息队列中取消息(不一 定以先进先出来取消息,也可以按照消息类型去取消息)这样就实现了进程间的通信。

2.消息队列的接口:

2.1创建消息队列

int msgget(key_ t key, int msgflg);

参数:

  • key:消息队列的标识符
  • msgflg:创建的标志,例如IPC_CREAT
  • IPC_CREAT:如果不存在就创建:按位或上一个权限(8进制的数字)

返回值:

  • 成功:返回队列ID
  • 失败:返回-1,并设置erron

2.2向消息队列发送消息

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

参数:

  • msgid:消息队列ID
  • msgp:指向msgbuf 的指针,用来指定发送的消息
    • 操作系统为该函数发送的消息定义了发送格式,只是定义了一部分,另一部分要程序员自己去定义

  • msgsz:要发送消息的长度,消息内容的长度
  • msgflg:创建标记,如果指定IPC_NOWAIT,失败会立即返回
    • 0:阻塞发送
    • IPC_NOWAIT:非阻塞发送

返回值:

  • 成功:返回0
  • 失败:返回-1,并设置erron

2.3接收消息:

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

参数:

  • msgid:消息队列ID
  • msgp:指向msgbuf的指针,用来接收消息
  • msgsz:要接收消息的长度
    • 注意:参数msgsz 指定由msgp 参数指向的结构的成员mtext的最大大小(以字节为单位)

msgtyp:接收消息的方式

  • 1. msgtyp = 0:读取队列中的第一条消息(不在乎当前对头元素时什么消息类型,将他当作普通队列来处理)
  • 2. msgtyp > 0:读取队列中类型为msgtyp 的第一条消息。(就是读取对列元素中第一个香蕉)除非在msgflg中指定了MSG_ EXCEPT, 将读取类型不等于msgtyp 绝对值的第一条消息
  • 3. msgtyp< : 0:读取队列中最小类型小于或等于msgtyp 绝对值的第一条消息

msgflg:创建标记,如果指定IPC_ NOWAIT,获取失败会立刻返回

返回值:

  • 成功返回实际读取消息的字节数
  • 失败返回-1,并设置erron

2.4操作消息队列的接口

int msgctl(int msqid, int cmd, struct msqid_ ds *buf);

参数:

  • msqid:消息队列ID
  • cmd:控制命令,
    • 例如IPC_ RMID,删除命令 ,
    • IPC STAT,获取状态
  • buf:存储消息队列的相关信息的buf

返回值:

  • 成功根据不同的cmd有不同的返回值,
  • 失败返回-1,并设置erron

2.5代码测试:

创建一个消息对列,写端发送消息对列,读端读取消息对列中的内容。

我们运行写端代码两次发现消息对列中写入20条消息,

运行读端代码我们发现成功读出

我们运行三次可以发现再无法从消息对列中读出,说明消息对列每次获取到消息后,就会将消息对列中相应的消息出对列

信号量:

信号量的原理

  • 信号量本质上就是资源计数器,能够保证多个进程之间访问临界资源,执行临 界区代码时,互斥访问。同时也可以用于同步

    • 临界资源:多个进程都可以访问到的资源(例如:同一块内存)
    • 临界区:访问临界资源时的代码,区域称之为临界区

互斥访问:同一时刻,多个进程当中,只有一个进程可以访问临界区资源。多个资源通过信号量保证互斥访问的时候,需要先获取信号量,如果能获取正确的信息量,则才能访问临界资源,如果获取不了,则阻塞等待。等待访问的进程将信号量设置为1,然后再访问。

  • 如果不进行互斥访问会造成结果二义性。(结果不同)(多核cpu同时运行多个进程访问临界资源,单核抢占式执行,操作系统调度不可控)
  • 同步:当临界资源空闲之后,通知等待的进程进行访问

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Java面试题冲刺第十六天--消息队列

    目录 面试题1:说说你对消息队列的理解,消息队列为了解决什么问题? 解耦 异步 削峰 追问1:消息队列有什么优缺点 面试题2:对于消息中间机,你们是怎么做技术选型的? 面试题3:如何确保消息正确地发送至 RabbitMQ?如何确保消息接收方消费了消息? 发送方确认模式 接收方确认机制 追问1:如何保证MQ消息的可靠传输? 总结 面试题1:说说你对消息队列的理解,消息队列为了解决什么问题? 我们公司业务系统一开始体量较小,很多组件都是单机版就足够,后来随着用户量逐渐扩大,我们程序也采用了微服务的设

  • Java消息队列的简单实现代码

    今天看到我们的招聘信息有对消息队列有要求,然后就思索了一翻,网上一搜一大堆. 我可以举个小例子先说明应用场景 假设你的服务器每分钟的处理量为200个,但客户端再峰值的时候可能一分钟会发1000个消息给你,这时候你就可以把他做成队列,然后按正常有序的处理,先进后出(LIFO),先进先出(FIFO)可根据自己的情况进行定夺 stack  先进后出(LIFO)--------Java 对应的类 Stack 队列 先进先出(FIFO)--------java对应的类Queue 这两种都可用Linkedl

  • java多线程消息队列的实现代码

    本文介绍了java多线程消息队列的实现代码,分享给大家,希望对大家有帮助,顺便也自己留个笔记 1.定义一个队列缓存池: //static修饰的成员变量和成员方法独立于该类的任何对象.也就是说,它不依赖类特定的实例,被类的所有实例共享. private static List<Queue> queueCache = new LinkedList<Queue>(); 2.定义队列缓冲池最大消息数,如果达到该值,那么队列检入将等待检出低于该值时继续进行. private Integer

  • Java中消息队列任务的平滑关闭详解

    前言 消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ 消息队列应用场景 消息队列在实际应用中常用的使用场景:异步处理,应用解耦,流量削锋和消息通讯四个场景. 本文主要给大家介绍的是关于Java中消息队列任务平滑关闭的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 1.问题背

  • Java实现Redis延时消息队列

    目录 什么是延时任务 延时任务的特点 实现思路: 代码实现 1.消息模型 2.RedisMq 消息队列实现类 3.消息生产者 4.消息消费者 5. 消息执接口 6. 任务类型的实现类:可以根据自己的情况去实现对应的队列需求 什么是延时任务 延时任务,顾名思义,就是延迟一段时间后才执行的任务.举个例子,假设我们有个发布资讯的功能,运营需要在每天早上7点准时发布资讯,但是早上7点大家都还没上班,这个时候就可以使用延时任务来实现资讯的延时发布了.只要在前一天下班前指定第二天要发送资讯的时间,到了第二天

  • Java进程间通信之消息队列

    目录 消息队列 1.消息队列的原理 2.消息队列的接口: 2.1创建消息队列 2.2向消息队列发送消息 2.3接收消息: 2.4操作消息队列的接口 2.5代码测试: 信号量: 信号量的原理 总结 消息队列 1.消息队列的原理 1.1 msgqueue采用链表来实现消息队列, 该链表是由系统内核维护, 1.2 系统中可能有很多的msgqueue, 每个MQ用消息队列描述符(消息队列ID: qid) 来区分,qid是唯一 的,用来区分不同的MQ. 1.3在进行进程间通信时,一个进程将消息加到MQ尾端

  • Python进程间通信Queue消息队列用法分析

    本文实例讲述了Python进程间通信Queue消息队列用法.分享给大家供大家参考,具体如下: 进程间通信-Queue Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信. 1. Queue的使用 可以使用multiprocessing模块的Queue实现多进程之间的数据传递,Queue本身是一个消息列队程序,首先用一个小实例来演示下Queue的工作原理: 代码如下: #coding=utf-8 from multiprocessing import Queue #初始化一个

  • Java redisTemplate阻塞式处理消息队列

    目录 Redis 消息队列 redis五种数据结构 队列生产者 队列消费者 测试类 并发情况下使用increment递增 补充 Redis 消息队列 redis五种数据结构 队列生产者 package cn.stylefeng.guns.knowledge.modular.knowledge.schedule; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; i

  • Java利用Redis实现消息队列的示例代码

    本文介绍了Java利用Redis实现消息队列的示例代码,分享给大家,具体如下: 应用场景 为什么要用redis? 二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成java对象; 主要是用到了ByteArrayOutputStream和ByteArrayInputStream; 注意:每个需要序列化的对象都要实现Serializable接口; 其代码如下: package Utils

  • PHP下操作Linux消息队列完成进程间通信的方法

    关于Linux系统进程通信的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/ 关于Linux系统消息队列的概念及实现可查看:http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/ PHP的sysvmsg模块是对Linux系统支持的System V IPC中的System V消息队列函数族的封装.我们需要利用sysvmsg模块提供的函数来进进程间通信.先来看一段示例代码_1:

  • Linux消息队列实现进程间通信实例详解

    Linux消息队列实现进程间通信实例详解 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度. 二.在Linux中使用消息队列 Linux提供了一系列消息队列的函数接口来让我们方便地使用

  • 详解Java消息队列-Spring整合ActiveMq

    1.概述 首先和大家一起回顾一下Java 消息服务,在我之前的博客<Java消息队列-JMS概述>中,我为大家分析了: 1.消息服务:一个中间件,用于解决两个活多个程序之间的耦合,底层由Java 实现. 2.优势:异步.可靠 3.消息模型:点对点,发布/订阅 4.JMS中的对象 然后在另一篇博客<Java消息队列-ActiveMq实战>中,和大家一起从0到1的开启了一个ActiveMq 的项目,在项目开发的过程中,我们对ActiveMq有了一定的了解: 1.多种语言和协议编写客户端

随机推荐