Java进程间通信之消息队列

 更新时间:2022年03月21日 14:57:48   作者:月半木斤  
这篇文章主要为大家详细介绍了Java进程间通信之消息队列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

消息队列

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同时运行多个进程访问临界资源,单核抢占式执行,操作系统调度不可控)
  • 同步:当临界资源空闲之后,通知等待的进程进行访问

总结

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

相关文章

  • 解决java编译错误:程序包不存在的问题

    解决java编译错误:程序包不存在的问题

    出错:Error:(3, 27) java: 程序包com.aliyun.odps.udf不存在,遇到这样的错误问题如何解决呢,下面小编给大家带来了java编译错误:程序包不存在的问题及解决方法,感兴趣的朋友一起看看吧
    2023-05-05
  • MyBatis中的SQL映射文件如何配置参数映射和使用方法

    MyBatis中的SQL映射文件如何配置参数映射和使用方法

    MyBatis 是一种开源的 Java 持久化框架,它可以自动将数据库中的数据映射到 Java 对象中,并且使得 Java 对象可以非常方便地存储到数据库中,本文将介绍 MyBatis 中 SQL 映射文件的参数映射配置和使用方法,需要的朋友可以参考下
    2023-07-07
  • SpringAOP切入点规范及获取方法参数的实现

    SpringAOP切入点规范及获取方法参数的实现

    这篇文章主要介绍了SpringAOP切入点规范及获取方法参数,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • Java中的锁ReentrantLock详解

    Java中的锁ReentrantLock详解

    这篇文章主要介绍了Java中的锁ReentrantLock详解,ReentantLock是java中重入锁的实现,一次只能有一个线程来持有锁,包含三个内部类,Sync、NonFairSync、FairSync,需要的朋友可以参考下
    2023-09-09
  • Java中ArrayBlockingQueue和LinkedBlockingQueue

    Java中ArrayBlockingQueue和LinkedBlockingQueue

    这篇文章主要介绍了Java中ArrayBlockingQueue和LinkedBlockingQueue,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下
    2022-09-09
  • Java substring方法实现原理解析

    Java substring方法实现原理解析

    这篇文章主要介绍了Java substring方法实现原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-05-05
  • Java中Tuple的功能及使用详解

    Java中Tuple的功能及使用详解

    Java中的Tuple是一种非常有用的数据结构,它可以让开发者在处理多个数据元素时更加方便和高效,通过Tuple,我们可以将多个变量打包成一个对象,从而减少了代码量,提高了代码可读性,这篇文章主要介绍了Java中Tuple的功能及使用场景,需要的朋友可以参考下
    2024-01-01
  • Java多线程编程中易混淆的3个关键字总结

    Java多线程编程中易混淆的3个关键字总结

    这篇文章主要介绍了Java多线程编程中易混淆的3个关键字总结,本文总结了、volatile、ThreadLocal、synchronized等3个关键字,对这几个容易混淆概念的关键字分别做了讲解,需要的朋友可以参考下
    2015-03-03
  • 解决idea每次打开新的项目都需要重新配置maven问题

    解决idea每次打开新的项目都需要重新配置maven问题

    这篇文章主要介绍了解决idea每次打开新的项目都需要重新配置maven问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • 一文带你快速学会JDBC及获取连接的五种方式

    一文带你快速学会JDBC及获取连接的五种方式

    JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统、通用的SQL数据库存取和操作的公共接口,下面这篇文章主要给大家介绍了关于如何通过一文带你快速学会JDBC及获取连接的五种方式,需要的朋友可以参考下
    2022-09-09

最新评论