netty学习笔记

netty线程模型

为了让NIO更好的利用多线程特性,Netty实现了Reactor线程模型。Reactor模型中有四个核心概念:

  1. Resources资源(请求/任务)
  2. Synchronous Event Demultiplexer 同步事件复用器
  3. Dispatcher 分配器
  4. Request Handler 请求处理器

Netty线程模型

EventLoopGroup

初始化过程

/*未完...*/

EventLoopGroup初始化过程
线程组本质上是循环创建多个NioEventLoop,通过executor创建.

@Override
protected EventLoop newChild(Executor executor,Object... args) throws Exception{
	return new NioEventLoop(this, executor,(SelectorProvider) args[0],((SelectStrategyFactory) args[1]).newSelectStrategy(), (RejectedExecutionHandler) args[2]);
}

EventLoop 将通道注册到EventLoop的selector上,进行事件轮询.在有线程在调用NioEventLoop的时候,判断executor方法的调用者是不是在EventLoop同一个线程,如果不是一个线程,则调用启动方法.

    public void execute(Runnable task) {
        if (task == null) {
            throw new NullPointerException("task");
        } else {
            boolean inEventLoop = this.inEventLoop();
            if (inEventLoop) {
                this.addTask(task);
            } else {
                this.startThread();
                this.addTask(task);
                if (this.isShutdown() && this.removeTask(task)) {
                    reject();
                }
            }

            if (!this.addTaskWakesUp) {
                this.wakeup(inEventLoop);
            }

        }
    }

		    @Override
            public void run() {
                thread = Thread.currentThread();
                if (interrupted) {
                    thread.interrupt();
                }

                boolean success = false;
                updateLastExecutionTime();
                try {//创建线程开始执行run方法,每个EventLoop都是执行run
                /*
					run执行两件事:Selector,select的事件 和 taskQueue里面的内容
				*/
                    SingleThreadEventExecutor.this.run();
                    success = true;
                } catch (Throwable t) {
                    logger.warn("Unexpected exception from an event executor: ", t);
                } finally {
                    if (state < ST_SHUTTING_DOWN) {
                        state = ST_SHUTTING_DOWN;
                    }

                    // Check if confirmShutdown() was called at the end of the loop.
                    if (success && gracefulShutdownStartTime == 0) {
                        logger.error("Buggy " + EventExecutor.class.getSimpleName() + " implementation; " +
                                SingleThreadEventExecutor.class.getSimpleName() + ".confirmShutdown() must be called " +
                                "before run() implementation terminates.");
                    }

启动

EventLoop自身实现了Executor接口,当调用executor方法提交任务时,则判断是否启动,未启动则调用内置的executor创建新县城来触发run方法执行.
eventLoop启动

Bind绑定端口过程

bind绑定过程
初始化Channel:
Channel channel = channelFactory.newChannel();
init(channel);
注册:

Channel

概念

netty中的Channel是一个抽象的概念,可以理解为对JDK NIO Channel的增强和扩展.增加了很多属性和方法.

AbstractChannel
-pipeline DefaultChannelPipeline //通道内时间处理链路
-eventLoop //绑定的EventLoop,用于执行操作
-unsafe Unsafe //提供I/O相关的操作的封装
# config() ChannelConfig //返回通道配置信息
+read() Channel //开始读数据,触发读取链路调用
+wirte(Object msg) ChannelFuture //写数据,触发链路调用
+bind(SocketAddress socketAddress) ChannelFuture //绑定

责任链模式

责任链模式为请求创建了一个处理对象的链.
发起请求和具体处理请求的过程进行解耦: 职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无需关心请求的处理细节和请求的传递.

Netty中事件的定义

inbound入站事件

事件描述
fireChannelRegisteredchannel注册事件
fireChannelUnregisteredchannel解除注册事件
fireChannelActivechannel活跃事件
fireChannelInactivechannel非活跃事件
fireExceptionCaught异常事件
fireUserEventTriggered用户自定义事件
fireChannelReadchannel读事件
fireChannelReadCompletechannel读完成事件
fireChannelWritabilityChangedchannel写状态变化事件

outbound出站事件

事件描述
bind端口绑定事件
connect连接事件
disconnect断开连接事件
close关闭事件
deregister解除注册事件
flush刷新数据到网络事件
read读事件,用于注册OP_READ到selector
write写事件
writeAndFlush写出数据事件

Pipeline中的handler是什么

ChannelHandler

用于处理I/O事件或拦截I/O操作,并转发到ChannelPipeline中的下一个处理器.这个顶级接口定义功能很弱,实际使用时会去实现下面两大子接口:

  1. 处理入站I/O事件的ChannelInboundHandler
  2. 处理出站I/O操作的ChannelOutboundHandler
适配器类

为了开发方便,避免所有的handler去实现一遍接口方法,Netty提供了简单的实现类:
ChanelInboundHandlerAdapter 处理入站I/O事件
ChannelOutboundHandlerAdapter 处理出站I/O操作
ChannelDuplexHandler 来支持同事处理入站和出站事件

ChannelHandlerContext

实际存储在Pipeline中的对象并非ChannelHandler,而是上线文对象,将Handler包裹在上下文对象中,通过上下文对象与它所属的ChannelPipeline交互,向上或向下传递事件或者修改pipeline都是通过上下文对象.

维护Pipeline中的handler

ChannelPipeline是线程安全的,ChannelHandler可以在任何时候添加或删除.

方法名称描述
addFirst最前面插入
addLast最后面插入
addBefore插入到指定处理器前面
addAfter插入到指定处理器后面
remove移除指定处理器
removeFirst
removeLast
replace替换指定处理器

Netty零拷贝机制

ByteBuf

JDK ByteBuffer 的缺点:

  1. 无法动态扩容
  2. API使用复杂

Netty的ByteBuf的优点:

  1. API操作便捷性
  2. 动态扩容
  3. 多种ByteBuf实现
  4. 高效的零拷贝机制

三个重要属性:

  1. capacity
  2. readerIndex 读取位置
  3. writerIndex 写入位置
在电子设计自动化(EDA)领域,Verilog HDL 是一种重要的硬件描述语言,广泛应用于数字系统的设计,尤其是在嵌入式系统、FPGA 设计以及数字电路教学中。本文将探讨如何利用 Verilog HDL 实现一个 16×16 点阵字符显示功能。16×16 点阵显示器由 16 行和 16 列的像素组成,共需 256 个二进制位来控制每个像素的亮灭,常用于简单字符或图形显示。 要实现这一功能,首先需要掌握基本的逻辑门(如与门、或门、非门、与非门、或非门等)和组合逻辑电路,以及寄存器和计数器等时序逻辑电路。设计的核心是构建一个模块,该模块接收字符输入(如 ASCII 码),将其转换为 16×16 的二进制位流,进而驱动点阵的 LED 灯。具体而言,该模块包含以下部分:一是输入接口,通常为 8 位的 ASCII 码输入,用于指定要显示的字符;二是内部存储,用于存储字符对应的 16×16 点阵数据,可采用寄存器或分布式 RAM 实现;三是行列驱动逻辑,将点阵数据转换为驱动 LED 矩阵的信号,包含 16 个行输出线和 16 个列使能信号,按特定顺序选通点亮对应 LED;四是时序控制,通过计数器逐行扫描,按顺序控制每行点亮;五是复用逻辑(可选),若点阵支持多颜色或亮度等级,则需额外逻辑控制像素状态。 设计过程中,需用 Verilog 代码描述上述逻辑,并借助仿真工具验证功能,确保能正确将输入字符转换为点阵显示。之后将设计综合到目标 FPGA 架构,通过配置 FPGA 实现硬件功能。实际项目中,“led_lattice”文件可能包含 Verilog 源代码、测试平台文件、配置文件及仿真结果。其中,测试平台用于模拟输入、检查输出,验证设计正确性。掌握 Verilog HDL 实现 16×16 点阵字符显示,涉及硬件描述语言基础、数字逻辑设计、字符编码和 FPGA 编程等多方面知识,是学习
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值