Java进程间通信之消息队列
作者:月半木斤 发布时间:2023-05-24 01:44:27
消息队列
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_CREATIPC_CREAT
:如果不存在就创建:按位或上一个权限(8进制的数字)
返回值:
成功:返回队列ID
失败:返回-1,并设置erron
2.2向消息队列发送消息
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数:
msgid
:消息队列IDmsgp
:指向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
:消息队列IDmsgp
:指向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
:消息队列IDcmd
:控制命令,例如
IPC_ RMID
,删除命令 ,IPC STAT
,获取状态buf:存储消息队列的相关信息的buf
返回值:
成功根据不同的cmd有不同的返回值,
失败返回-1,并设置erron
2.5代码测试:
创建一个消息对列,写端发送消息对列,读端读取消息对列中的内容。
我们运行写端代码两次发现消息对列中写入20条消息,
运行读端代码我们发现成功读出
我们运行三次可以发现再无法从消息对列中读出,说明消息对列每次获取到消息后,就会将消息对列中相应的消息出对列
信号量:
信号量的原理
信号量本质上就是资源计数器,能够保证多个进程之间访问临界资源,执行临 界区代码时,互斥访问。同时也可以用于同步
临界资源:多个进程都可以访问到的资源(例如:同一块内存)
临界区:访问临界资源时的代码,区域称之为临界区
互斥访问:同一时刻,多个进程当中,只有一个进程可以访问临界区资源。多个资源通过信号量保证互斥访问的时候,需要先获取信号量,如果能获取正确的信息量,则才能访问临界资源,如果获取不了,则阻塞等待。等待访问的进程将信号量设置为1,然后再访问。
如果不进行互斥访问会造成结果二义性。(结果不同)(多核cpu同时运行多个进程访问临界资源,单核抢占式执行,操作系统调度不可控)
同步:当临界资源空闲之后,通知等待的进程进行访问
来源:https://blog.csdn.net/weixin_45897952/article/details/123604519


猜你喜欢
- 线程调用类对象在前面的示例中,我们为线程任务使用了通常的函数。实际上,我们可以使用任何可调用对象或者lambda函数,如下调用类对象的例子:
- 思路如下:创建一个类,通过extends使其继承窗体类JFrame;创建一个JFrame对象,使用JFrame类的setVisible()方
- 什么是Mapping同样的,我们先讲基本概念,什么是mapping,上节给大家简要的举了一个例子,还有印象吗?mapping是es中一个比较
- 我们在编程的时候,有时会使用多线程来解决问题,比如你的程序需要在后台处理一大堆数据,但还要使用户界面处于可操作状态;或者你的程序需要访问一些
- 方法参数public String listFireEvent(@Valid FireSearch fireSearch, Ht
- 通过javamail 实现发送邮件,供大家参考,具体内容如 * 意:服务器有些端口是没有开放的 需要去开放端口。 有些邮箱是需要开启对应授权服
- 本文实例为大家分享了flutter实现底部导航栏切换的具体代码,供大家参考,具体内容如下思路:MaterialApp是提供了bottomna
- 当maven需要到的依赖jar包不在本地仓库时, 就需要到远程仓库下载 .这个时候如果mavensetting.xml中配置了镜像 , 而且
- 本文实例为大家分享了Android使用SoundPool播放音效的具体代码,供大家参考,具体内容如下SoundPool(int maxStr
- 首先我们知道:JVM发生内存错误的类型1、堆内存泄漏:OutOfMemory:Java heap space此种内存泄漏,增加内存,只能暂时
- 内存泄露内存泄漏就是在当前应用周期内不再使用的对象被GC Roots引用,导致不能回收,使实际可使用内存变小,通俗点讲,就是无法回收无用对象
- 在开发的过程中大家一般都会选择使用数据线连接的方式进行调试,但是有些时候比如使用模拟器时就不能这样了,所以有必要来研究下怎么使用adb通过w
- 理解圆弧绘制GDI+中对于圆弧的绘制,是以给定的长方形(System.Drawing.Rectangle 结构)为边界绘制的椭圆的
- 1、Java版package com.lyz.utils.common; import java.io.UnsupportedEncodin
- 首先,想要明白hashCode的作用,你必须要先知道Java中的集合。 总的来说,Java中的集合(Collection)有两类,一类是Li
- EntityWrapper的常用方法#WHERE (issue_type = ?) AND (status = ? OR status =
- 大家都知道 Android 的 Activity 是存着历史栈的,比如从 A -> B -> C,C 完成 finish 后回到
- 前言idea作为一个java开发的便利IDE工具,个人是比较喜欢的,今天来探索个小功能: 导出单个类文件为jar包!JAR文件的全称是Jav
- 开始以前,先认识一下WinForm控件数据绑定的两种形式,简单数据绑定和复杂数据绑定。1. 简单的数据绑定例1using (SqlConne
- using System;using System.Collections.Generic;using System.Net;using S