SpringBoot整合rabbitmq使用案例

news2024/9/22 9:40:06

RocketMQ(二十四)整合SpringBoot

SpringBoot整合rabbitmq使用案例

    • 一 SpringBoot整合RocketMQ实现消息发送和接收
      • 消息生产者
        • 1)添加依赖
        • 2)配置文件
        • 3)启动类
        • 4)测试类
      • 消息消费者
        • 1)添加依赖
        • 2)配置文件
        • 3)启动类
        • 4)测试类
        • 5)RocketMQMessageListener参数
      • 测试
    • RocketMQ发送同步消息
      • 同步消API介绍
    • RocketMQ发送异步消息
      • 异步消息API介绍
    • RocketMQ发送单向消息
    • RocketMQ消费者广播模式和负载均衡模式
    • RocketMQ实现顺序消息
    • RocketMQ实现延迟消息

一 SpringBoot整合RocketMQ实现消息发送和接收

消息生产者

1)添加依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
        </dependency>
2)配置文件
server:
  port: 8081
  servlet:
    context-path: /

rocketmq:
  name-server: 127.0.0.1:9876
  producer:
    group: producer-demo1
3)启动类


@SpringBootApplication
public class RocketmqProducerApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(RocketmqProducerApplication.class, args);
    }
}

4)测试类
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {RocketmqProducerApplication.class})
public class ProducerTest {
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Test
    public void ConvertAndSendTest() {
        rocketMQTemplate.convertAndSend("springboot-mq", "hello springboot rocketmq");
    }
    
}

消息消费者

1)添加依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
        </dependency>
2)配置文件
server:
  port: 8084
  servlet:
    context-path: /

rocketmq:
  name-server: 127.0.0.1:9876
  consumer:
    group: consumer-demo1
3)启动类
@SpringBootApplication
public class RocketmqConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(RocketmqConsumerApplication.class, args);
    }
}

4)测试类
@RocketMQMessageListener(topic = "springboot-mq",consumerGroup = "${rocketmq.consumer.group}")
@Component
public class ConsumerService implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("收到消息内容:"+message);
    }
}

5)RocketMQMessageListener参数
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RocketMQMessageListener {
    String NAME_SERVER_PLACEHOLDER = "${rocketmq.name-server:}";
    String ACCESS_KEY_PLACEHOLDER = "${rocketmq.consumer.access-key:}";
    String SECRET_KEY_PLACEHOLDER = "${rocketmq.consumer.secret-key:}";
    String TRACE_TOPIC_PLACEHOLDER = "${rocketmq.consumer.customized-trace-topic:}";
    String ACCESS_CHANNEL_PLACEHOLDER = "${rocketmq.access-channel:}";
    /**
     * 消费者分组
     *
     * @return
     */
    String consumerGroup();
    /**
     * 主题
     */
    String topic();
    /**
     * selectorType:消息选择器类型
     * - SelectorType.TAG:默认值,根据TAG选择,仅支持表达式格式如:“tag1 || tag2 || tag3”,如果表达式为null或者“*”标识订阅所有消息
     * - SelectorType.SQL92:根据SQL92表达式选择
     */
    SelectorType selectorType() default SelectorType.TAG;
    /**
     * selectorType 对应的表达式
     */
    String selectorExpression() default "*";
    /**
     * consumeMode:消费模式
     * - ConsumeMode.CONCURRENTLY:默认值,并行处理
     * - ConsumeMode.ORDERLY:按顺序处理
     */
    ConsumeMode consumeMode() default ConsumeMode.CONCURRENTLY;
    /**
     * messageMode:消息模型
     * - MessageModel.CLUSTERING:默认值,集群
     * - MessageModel.BROADCASTING:广播
     */
    MessageModel messageModel() default MessageModel.CLUSTERING;
    /**
     * 最大线程数,默认值 64
     */
    int consumeThreadMax() default 64;
    /**
     * 消费失败,最大重试次数
     * <p>
     * - 在并发模式中,-1表示16
     * - 在有序模式中,-1表示整数最大值
     */
    int maxReconsumeTimes() default -1;
    /**
     * 消息可能阻止使用线程的最长时间(分钟)
     */
    long consumeTimeout() default 15L;
    /**
     * 发送回复消息超时
     */
    int replyTimeout() default 3000;
    /**
     * 默认值 ${rocketmq.consumer.access-key:}
     */
    String accessKey() default ACCESS_KEY_PLACEHOLDER;
    /**
     * 默认值 ${rocketmq.consumer.secret-key:}
     */
    String secretKey() default SECRET_KEY_PLACEHOLDER;
    /**
     * 启用消息轨迹,默认值 false
     */
    boolean enableMsgTrace() default false;
    /**
     * 自定义的消息轨迹主题,默认值${rocketmq.consumer.customized-trace-topic:}
     * 没有配置此配置项则使用默认的主题
     */
    String customizedTraceTopic() default TRACE_TOPIC_PLACEHOLDER;
    /**
     * 命名服务器地址,默认值${rocketmq.name-server:}
     */
    String nameServer() default NAME_SERVER_PLACEHOLDER;
    /**
     * 默认值${rocketmq.access-channel:}
     */
    String accessChannel() default ACCESS_CHANNEL_PLACEHOLDER;
}

测试

运行生产者中ConvertAndSendTest测试方式,观察消费者监听器日志

RocketMQ发送同步消息

发送同步消息是指producer向 broker 发送消息,执行 API 时同步等待, 直到broker 服务器返回发送结
果;
相对异步发送消息,同步会阻塞线程,性能相对差点,但是可靠性高,这种方式得到广泛使用,比如:
短信通知,邮件通知,站内重要信息通知等。
RocketMQTemplate 给我们提供了syncSend方法(有多个重载),来实现发送同步消息;
下面给一个实例:

    /**
     * 发送同步消息
     */
    @Test
    public void sendSyncMessageTest() {
        for (int i = 0; i < 10; i++) {
            SendResult sendResult = rocketMQTemplate.syncSend("springboot-mq", "rocketmq同步消息!" + i);
            System.out.println(sendResult);
        }
    }

这里执行完发送同步消息返回执行结果 SendResult ;

同步消API介绍

//发送普通同步消息-Object
syncSend(String destination, Object payload)
//发送普通同步消息-Message
syncSend(String destination, Message<?> message)
//发送批量普通同步消息
syncSend(String destination, Collection<T> messages)
//发送普通同步消息-Object,并设置发送超时时间
syncSend(String destination, Object payload, long timeout)
//发送普通同步消息-Message,并设置发送超时时间
syncSend(String destination, Message<?> message, long timeout)
//发送批量普通同步消息,并设置发送超时时间
syncSend(String destination, Collection<T> messages, long timeout)
//发送普通同步延迟消息,并设置超时
syncSend(String destination, Message<?> message, long timeout, int delayLevel)
/**
 * 批量消息
 */
@Test
void asyncSendBatch() {
    Message<String> msg = MessageBuilder.withPayload("hello world test1").build();
    List<Message> msgList = Arrays.asList(msg,msg,msg,msg,msg);
    SendResult res = rocketMQTemplate.syncSend("first-topic-str:tag1", msgList);
    log.info("批量消息");
}

RocketMQ发送异步消息

发送异步消息是指producer向 broker 发送消息时指定消息发送成功及发送异常的回调方法,调用 API
后立即返回,producer发送消息线程不阻塞 ,消息发送成功或失败的回调任务在一个新的线程中执行

相对发送同步消息,异步消息性能更高,可靠性略差。适合对响应时间要求高的业务场景。
RocketMQTemplate 给我们提供了asyncSend方法(有多个重载),来实现发送异步消息;

    /**
     * 异步消息-String
     * 指发送方发出数据后,不等接收方发回响应,接着发送下个数据包
     * 关键实现异步发送回调接口(SendCallback)
     * 在执行消息的异步发送时应用不需要等待服务器响应即可直接返回,通过回调接口接收务器响应,并对服务器的响应结果进行处理
     * 这种方式任然需要返回发送消息任务的执行结果,异步不影响后续任务,不会造成阻塞
     */
    @Test
    public void sendAsyncMessage() {
        for (int i = 0; i < 10; i++) {
            rocketMQTemplate.asyncSend("springboot-mq", "rocketmg异步消息!" + i,
                    new SendCallback() {
                        @Override
                        public void onSuccess(SendResult sendResult) {
                            System.out.println("发送成功!");
                        }

                        @Override
                        public void onException(Throwable throwable) {
                            System.out.println("发送失败!");
                        }
                    });
        }
    }

类似发送同步消息,多了一个SendCallback回调接口参数,实现onSuccess和onException方法,分别
表示异步发送成功和失败;
在这里插入图片描述

异步消息API介绍

//发送普通异步消息-Object
asyncSend(String destination, Object payload, SendCallback sendCallback)
//发送普通异步消息-Message
asyncSend(String destination, Message<?> message, SendCallback sendCallback)
//发送普通异步消息-Object,并设置发送超时时间
asyncSend(String destination, Object payload, SendCallback sendCallback, long timeout)
//发送普通异步消息-Message,并设置发送超时时间
asyncSend(String destination, Message<?> message, SendCallback sendCallback, long timeout)
//发送普通异步延迟消息,并设置超时
asyncSend(String destination, Message<?> message, SendCallback sendCallback, long timeout, int delayLevel)

RocketMQ发送单向消息

发送单向消息是 指producer向 broker 发送消息,执行 API 时直接返回,不等待broker 服务器的结果
这种方式主要用在不特别关心发送结果的场景,举例:日志发送
RocketMQTemplate 给我们提供了sendOneWay方法(有多个重载),来实现发送单向消息;
下面给一个实例:

  /**
     * 单向消息
     * 特点为只负责发送消息,不等待服务器回应且没有回调函数触发,即只发送请求不等待应答
     * 此方式发送消息的过程耗时非常短,一般在微秒级别
     * 应用场景:适用于某些耗时非常短,但对可靠性要求并不高的场景,例如日志收集
     */
    @Test
    public void sendOneWayMessage() {
        for (int i = 0; i < 10; i++) {
            rocketMQTemplate.sendOneWay("springboot-mq", "rocketmg单向消息!" + i);
        }
    }

RocketMQ消费者广播模式和负载均衡模式

在这里插入图片描述
如上图,假如我们有多个消费者,消息生产者发送的消息,是每一个消费者都消费一次呢?还是通过一
些机制,比如轮询机制,每个消息只被某一个消费者消费一次呢?
这里涉及到消费者的消费模式,一种是广播模式,还有一种是负载均衡模式;

  • 广播模式是每个消费者,都会消费消息;
  • 负载均衡模式是每一个消息只会被某一个消费者消费一次;

我们业务上一般用的是负载均衡模式,当然一些特殊场景需要用到广播模式,比如发送一个信息到邮
箱,手机,站内提示;
我们可以通过 @RocketMQMessageListenermessageModel 属性值来设置,
MessageModel.BROADCASTING 是广播模式MessageModel.CLUSTERING 是默认集群负载均衡模式
我们先集群负载均衡测试,加上 messageModel=MessageModel.CLUSTERING


/**
 * @ClassName: ConsumerService
 * @Description: 消息消费者
 * @Author wxl
 * @Date 2024-04-22
 * @Version 1.0.0
 **/
@RocketMQMessageListener(topic = "springboot-mq",consumerGroup = "${rocketmq.consumer.group}",messageModel = MessageModel.CLUSTERING)
@Component
public class ConsumerService implements RocketMQListener<String> {

    @Override
    public void onMessage(String message) {
        System.out.println("收到消息内容:"+message);
    }
}

RocketMQ实现顺序消息

rocketmq默认发送的消息是进入多个消息队列,然后消费端多线程并发消费,所以默认情况,不是顺序消费消息的;
在这里插入图片描述
有时候,我们需要实现顺序消费一批消息,比如电商系统,订单创建,支付,完成等操作,需要顺序执行;
RocketMQTemplate 给我们提供了SendOrderly方法(有多个重载),来实现发送顺序消息;包括以下:
syncSendOrderly,发送同步顺序消息;
asyncSendOrderly,发送异步顺序消息;
sendOneWayOrderly,发送单向顺序消息;
一般我们用第一种发送同步顺序消息;
在这里插入图片描述
第三个参数hashKe,方法点进去:
在这里插入图片描述
因为broker会管理多个消息队列,这个hashKey参数,主要用来计算选择队列的,一般可以把订单ID,
产品ID作为参数值;
发送到一个队列,这样方便搞顺序队列;
以及消费端接收的时候,默认是并发多线程去接收消息。RocketMQMessageListener有个属性
consumeMode,默认是ConsumeMode.CONCURRENTLY ,我们要改成ConsumeMode.ORDERLY,
单线程顺序接收消息;
下面给具体事例,模拟两个订单发送消息;

消息生产者端:

    /**
     * 发送同步顺序消息
     */
    public void sendOrderlyMessage() {
        // hashKey用来计算决定消息发送到哪个消息队列    一般是订单ID,产品ID等
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,创建", "98456231");
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,支付", "98456231");
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456231,完成", "98456231");
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,创建", "98456232");
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,支付", "98456232");
        rocketMQTemplate.syncSendOrderly("java1234-rocketmq-orderly", "98456232,完成", "98456232");
    }

消费者端:

@RocketMQMessageListener(topic = "java1234-rocketmq-orderly",
        consumerGroup = "${rocketmq.consumer.group}", consumeMode = ConsumeMode.ORDERLY)
@Component
public class ConsumerService implements RocketMQListener<String> {
    @Override
    public void onMessage(String s) {
        System.out.println("消费者:收到消息内容:" + s);
    }
}

运行测试:

在这里插入图片描述

RocketMQ实现延迟消息

延迟消息
对于消息中间件来说,producer 将消息发送到mq的服务器上,但并不希望这条消息马上被消费,
而是推迟到当前时间节点之后的某个时间点,再将消息投递到 queue 中让 consumer 进行消费。

延迟消息的使用场景很多,一种比较常见的场景就是在电商系统中,订单创建后,会有一个等待用
户支付的时间窗口,一般为30分钟,30分钟后 customer 会收到这条订单消息,然后程序去订单表中检
查当前这条订单的支付状态,如果是未支付的状态,则自动清理掉,这样就不需要使用定时任务的方式
去处理了。

Rocket的延迟消息
RocketMQ 支持定时的延迟消息,但是不支持任意时间精度,仅支持特定的 level,例如定时 5s,
10s, 1m 等。其中,level=0 级表示不延时,level=1 表示 1 级延时,level=2 表示 2 级延时,以此类
推。

messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h

在这里插入图片描述
我们会发现,所有消息发送方法都有一个带int类型的delayLevel参数重载方法,这个就是设置延迟消息
级别的参数。
同时注意,每个带delayLevel参数的方法,也同时带有long类型的timeout参数,这个是设置消息发送超
时时间,默认是3秒,我们也可以自行设置;
同时还有 Message参数,如果发送这种类型的消息,可以携带具体的消息数据;

    /**
     * 发送延迟消息
     */
    @Test
    public void sendDelayMessage() {
        rocketMQTemplate.syncSend("java1234-rocketmq", MessageBuilder.withPayload("rocketmq延迟1秒消息").build(), 3000, 1);
        rocketMQTemplate.syncSend("java1234-rocketmq", MessageBuilder.withPayload("rocketmq延迟5秒消息").build(), 3000, 2);
        rocketMQTemplate.syncSend("java1234-rocketmq", MessageBuilder.withPayload("rocketmq延迟10秒消息").build(), 3000, 3);
    }

运行测试:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1645710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sy9-dhcp/dns服务配置

前言、 课程需要&#xff08;进入服务器综合配置使用阶段了&#xff09;&#xff0c;这里还是沿用桌面版的ubuntu来配置dhcp和dns&#xff0c;这里updated了新的版本。2024.5 server端环境&#xff1a; Win11VMS&#xff1a;192.168.105.1192.168.105.128 &#xff08;ubuntu…

AI热潮开始退去,财务压力迫使多家硅谷明星初创公司选择退出

曾风光无限的Stability AI已重组并削减业务规模&#xff0c;Inflection AI更是关闭业务并基本并入微软。 5月4日消息&#xff0c;国外媒体日前撰文指出&#xff0c;人工智能的热潮已开始逐渐褪去。初创公司想要同微软、谷歌等科技巨头在人工智能领域一决高下&#xff0c;门槛已…

Spring IoCDI(2)—IoC详解

目录 一、IoC详解 1、Bean的存储 &#xff08;1&#xff09;Controller&#xff08;控制器存储&#xff09; 获取bean对象的其他方式 Bean 命名约定 &#xff08;2&#xff09;Service&#xff08;服务存储&#xff09; &#xff08;3&#xff09;Repository&#xff08…

SPA模式下的多页面跳转原理及实现——jQuery Mobile为例

jQuery Mobile在SPA模式下的多页面跳转原理及实现案例 文章目录 jQuery Mobile在SPA模式下的多页面跳转原理及实现案例前言一、SPA的实现原理和代码分析1.实现原理说明&#xff08;1&#xff09;index.html&#xff08;2&#xff09;index.js&#xff08;3&#xff09;page2.ht…

kafka日志存储

前言 kafka的主题(topic)可以对应多个分区(partition)&#xff0c;而每个分区(partition)可以有多个副本(replica)&#xff0c;我们提生产工单创建topic的时候也是要预设这些参数的。但是它究竟是如何存储的呢&#xff1f;我们在使用kafka发送消息时&#xff0c;实际表现是提交…

一款开源高性能AI应用框架

前言 LobeChat 是一个基于 Next.js 框架构建的 AI 会话应用&#xff0c;旨在提供一个 AI 生产力平台&#xff0c;使用户能够与 AI 进行自然语言交互。 LobeChat应用架构 LobeChat 的整体架构由前端、EdgeRuntime API、Agents 市场、插件市场和独立插件组成。这些组件相互协作&a…

38-1 防火墙了解

一、防火墙的概念: 防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网(US5606668 [A]1993-12-15)。它是一种位于内部网络与外部网络之间的网络安全系统,是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。…

4个可将 iPhone iPad iPod 修复至正常状态的 iOS 系统恢复软件

许多iOS用户对操作系统问题感到恐慌&#xff0c;例如iPhone卡在恢复模式、白屏死机、黑屏死机、iOS系统损坏、iTunes连接屏幕、iPhone数据丢失等。这些状态通常很无聊&#xff0c;因为您无法使用 iPhone 执行任何操作。 4个可将 iPhone iPad iPod 修复至正常状态的 iOS 系统恢复…

【Unity 组件思想-预制体】

【Unity 组件思想-预制体】 预制体&#xff08;Prefab&#xff09;是Unity中一种特殊的组件 特点和用途&#xff1a; 重用性&#xff1a; 预制体允许开发者创建可重复使用的自定义游戏对象。这意味着你可以创建一个预制体&#xff0c;然后在场景中多次实例化它&#xff0c;…

sip转webrtc方案

技术选型 由于很多企业会议协议用的主要是webrtc&#xff0c;但是项目上很多时候的一些旧设备只支持sip协议&#xff0c;并不支持webrtc协议。所以sip和webrtc的相互转换就很有必要。 流媒体服务mediasoup本身并不支持sip协议。那么如何实现sip转webrtc呢&#xff1f; 根据调研…

我独自升级崛起下载教程 我独自升级崛起怎么一键下载

定于5月8日全球盛大发布的动作RPG力作《我独自升级崛起》&#xff0c;基于备受追捧的同名动画及网络漫画&#xff0c;誓为热情洋溢的游戏爱好者们呈献一场深度与广度兼具的冒险盛宴。这款游戏巧妙融合网络武侠元素&#xff0c;其创意十足的设计框架下&#xff0c;核心叙述聚焦于…

[极客大挑战 2019]PHP

1.通过目录扫描找到它的备份文件&#xff0c;这里的备份文件是它的源码。 2.源码当中涉及到的关键点就是魔术函数以及序列化与反序列化。 我们提交的select参数会被进行反序列化&#xff0c;我们要构造符合输出flag条件的序列化数据。 但是&#xff0c;这里要注意的就是我们提…

力扣每日一题109:有序链表转换二叉搜索树

题目 中等 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为 平衡 二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0&#xff0c;-3,9&#xff0c;-10,null,5]&#xff0c;它…

video标签,如何隐藏右下角三个点包含的功能?

// nodownload: 不要下载 // nofullscreen: 不要全屏 // noremoteplayback: 不要远程回放 // disablePictureInPicture: 不要画中画 <videocontrols disablePictureInPicture"true"controlslist"nodownload nofullscreen noremoteplayback" > </v…

Java基础教程 - 5 数组

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 5 数组 前面我们保存数据…

Java毕设之学院党员管理系统的设计与实现

运行环境 环境说明: 开发语言:java 框架:springboot&#xff0c;vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7&#xff0c;8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) Maven包:Maven3.3.9 系统实现 管理员功能实现 党员管理 管理员进入指定功能操作…

AI 不仅会画画,还能造车 | 最新快讯

本周的北京&#xff0c;正在上演一场深刻的变革。 汽车产业&#xff0c;这个曾经以工业制造为核心的行业&#xff0c;正迅速地被数字化浪潮所改变&#xff0c;汽车、电商、互联网、人工智能等领域的界限变得模糊。在这样的背景下&#xff0c;车企们纷纷开始打破传统&#xff0c…

【AI】深度学习框架的期望与现实 机器学习编译尚未兑现其早期的一些承诺……

深度学习框架的期望与现实 机器学习编译尚未兑现其早期的一些承诺…… 来自&#xff1a;Axelera AI 资深软件工程师 Matthew Barrett 原帖是linkedin帖子&#xff1a; https://linkedin.com/posts/matthew-barrett-a49929177_i-think-its-fair-to-say-that-ml-compilation-ac…

【driver2】设备读写,同步和互斥,ioctl,进程休眠,时间和延时,延缓

文章目录 1.实现设备读写&#xff1a;write函数中一个进程写没问题&#xff0c;两进程写&#xff1a;第一个进程运行到kzalloc时&#xff0c;第二个进程也执行了kzalloc&#xff0c;只第二个进程地址保存在c中&#xff0c;第一个进程分配内存空间地址丢失造成内存泄漏。第一个进…

【Three.js基础学习】14.Galaxy Generator

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 前言 课程知识点 1. 实现星际编辑器 2. 创建粒子 1000&#xff0c; 在随机位置 3. 创建材质 PointsMaterial 4. Points() 接收 5. 放到gui 中调试 但是会发现调整size 等 属…