深入理解Netty底层基础、中断、NIO、epoll~~~~

2023-11-02

深入理解Netty底层基础

LInux 操作系统中断

什么是系统中断

这个没啥可说的,大家都知道;

CPU 在执行任务途中接收到中断请求,需要保存现场后去处理中断请求!保存现场称为中断处理程序!处理中断请求也就是唤醒对应的任务进程来持有CPU进行需要的操作!

有了中断之后,提升了操作系统的性能!可以异步并行处理很多任务!

  • 软中断(80中断)

由CPU产生的;CPU检查到程序代码段发生异常会切换到内核态;

  • 硬中断

由硬件设备发起的中断称为硬中断!可以发生在任何时间;比方说网卡设备接收到一组报文;对应的报文会被DMA设备进行拷贝到网卡缓冲区!然后网卡就会向CPU发起中断信号(IRQ):

CPU收到信号后就会执行网卡对应的中断处理程序!

内核在系统中断时做了什么事

每种中断都有它对应的中断处理程序;

对应到内核的某一个代码段;

CPU接收到中断后;首先需要将寄存器中数据保存到进程描述符!PCB!

随后切换到内核态处理中断处理程序!执行网卡的程序;

执行完毕之后切换到用户态,根据PCB内容恢复现场!然后就可继续执行代码段了!

硬件中断触发的过程

中断请求寄存器: 保存需要发送中断请求的设备记录!

优先级解析器:中断请求是有优先级之分的,因为CPU不能同时执行多个中断请求!

正在服务寄存器:正在执行的请求!比方我正在打字,这里面记录的就是键盘IRQ1 !

操作系统启动时需要将硬件向量值与处理程序地址进行映射!当硬件发送中断信息时只会发送向量值,通过匹配找到对应的处理程序!

Socket基础

Socket读写缓冲区机制

所谓socket,在底层也无非就是一个对象,通过对象绑定两个缓冲区,也就是数据队列,然后调用系统API对这两个缓冲区的数据进行操作罢了!

发数据;用户态转内核态,将数据拷贝到send缓存区,然后调用write系统调用将数据拷贝到网卡,再由网卡通过TCP/IP协议进行数据包的网络发送!

socket两种工作模式

  • BIO

总结:读数据读不到就一直等,发数据发不了就一直等!

  • NIO

读数据读不到就等一会再读,取数据取不到就等一会再取!

接受端缓冲区打满了,线程又抢占不到CPU去清理缓冲区,怎么办!

最后发送端的数据缓冲区也会被打满!

系统调用;用户态------内核态

  • 系统调用

int 0X80对应的就是系统调用中断处理程序;向量值为128;system_call;

IRQ是有限的,不可能为每一个系统调用都分配一个向量值,所以统一使用80中断来进行系统调用的路由!

为什么要有这两种状态

指令的危险程度不一样;

对于不同的指令,为了保证系统安全,划分了用户空间和内核空间;

linux中:0表示内核态,3表示用户态!

所以:linux在创建进程的时候就会为进程分配两块空间;

用户栈:分配变量,创建对象

内核栈:分配变量!

什么时候进程进行切换至内核态

硬中断;

用户态中代码出现错误也要切换!

进程切换时都做了什么

CPU中存在很多寄存器

这些寄存器保存了进程在进行运算时的一些瞬时数据;如果现在要进行进程切换了;这些数据都需要找个地方保存起来;那么保存到哪里呢?

进程PCB:在OS创建进程的时候同时也会分配一段空间存放进程的一些信息;其中就有一个字段指向一个数据结构;叫做进程控制块PCB:

用来描述和控制进程的运行的一个数据结构——进程控制块PCB(Process Control Block),是进程实体的一部分,是操作系统中最重要的记录型数据结构。

  • PCB是进程存在的唯一标志
  • 系统能且只能通过PCB对进程进行控制和调度
  • PCB记录了操作系统所需的、用于描述进程的当前情况以及控制进程运行的全部信息

所以:在进程进行切换的时候CPU中的数据保存到了PCB中,供CPU回来时读取恢复!

Linux select 多路复用函数

select就是一个函数:只要传入相应的参数就能获得相应的数据:

1、我们所关心的文件描述符fd;

2、描述符中我们关心的状态:读事件、写事件、等

3、等待时间

调用结束后内核会返回相关信息给我们!

做好准备的个数

哪些已经做好准备;有了这些返回信息,我们就可以调用合适的IO函数!这些函数就不会再被阻塞了;-

  • 函数详解
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, timeval *timeout)
    
- maxfdp1 readset 和 wirteset中的最大有数据位
- readset  bitmap结构的位信息;保存我们需要读取的socket序号;
- writeset 写数据信息
- exceptset 异常信息

使用详解

将函数需要的参数准备好之后调用select;

select进行80中断;将rset数据拷贝到内核中;查询对应的状态之后设置rset对应的位置值,

完成后又拷贝到用户态中的rset;这样一来rset里面的位信息就代表了哪些socket是准备好了的!

随后遍历这些位信息就可以调用read或wirte进行缓冲区的操作了!

缺点

可以看到,while死循环中每次执行都将rset重新置位;然后循环重新SET位信息;随后才会发起请求!过程较为繁琐且重复!

select多路复用器底层原理分析

epoll函数

了解到select的缺点后发现:select每次得到数据都要进行复位,然后又进行重复的步骤去内核中获取信息;感觉就是很多时间都花在重复的劳动上,为了解决这个问题,linux在2.6引入epoll模型,单独在内核区域开辟一块空间来做select主动去做的事,select是主动查,epoll则是准备数据,线程来了直接取就行了;大大提升了性能

既然是函数,看看相关的函数实现:

实现思路:

在内核创建一块空间;总所周知;linux下一切皆文件;所以所谓创建的空间也就是一个文件描述符fd,然后这个文件结构中有两个指针指向另外两个地址空间:事件队列、就绪队列

事件队列:存放已经建立所有socket连接

就绪队列:准备就绪的socket;也就是read或write的时候不用阻塞的socket;

其实epoll就像一个数据库;里面有两个数据表;一个放连接列表;一个放准备就绪的连接列表;

既然有这两个队列;就要涉及到增删查;这就是另外两个函数的来由;

创建epoll空间
int epoll_create(int size);


int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

对事件队列进行增删改:
epfd : epoll的文件描述符号:因为内核中可能有多个epoll
op : 参数op有以下几个值: EPOLL_CTL_ADD:注册新的fd到epfd中,并关联事件event; EPOLL_CTL_MOD:修改已经注册的fd的监听事件; EPOLL_CTL_DEL:从epfd中移除fd,并且忽略掉绑定的event,这时event可以为null;
fd : 表示socket对应的文件描述符。

epoll底层原理解析

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深入理解Netty底层基础、中断、NIO、epoll~~~~ 的相关文章

  • 为什么 OS X 和 Linux 之间的 UTF-8 文本排序顺序不同?

    我有一个包含 UTF 8 编码文本行的文本文件 mac os x cat unsorted txt foo foo 津 如果它有助于重现问题 这里是文件中确切字节的校验和和转储 以及如何自己生成文件 在 Linux 上 使用base64 d
  • bash while 循环的布尔表达式中的 -lt 意味着什么?

    我猜测它代表小于基于输出 但是我在哪里可以找到有关此语法的文档 bin bash COUNTER 0 while COUNTER lt 10 do echo The counter is COUNTER let COUNTER COUNTE
  • Ruby:在 Ubuntu 上安装 rmagick

    我正在尝试在 Ubuntu 10 04 上安装 RMagick 看起来here https stackoverflow com questions 1482823 is there an easy way to install rmagic
  • Crontab 每 5 分钟一次 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我如何告诉 crontab 每 5 分钟运行一次 但从每小时的第二分钟开始 换句话说 我想在以下时间执行我的脚本minute 5 2 例如 我的脚本应
  • “git add”返回“致命:外部存储库”错误

    我刚刚进入 git 的奇妙世界 我必须提交我对程序所做的一系列更改 位于名为的目录中 var www myapp 我创建了一个新目录 home mylogin gitclone 从这个目录中 我做了一个git clone针对公共回购 我能够
  • 如何从 C++ 程序中重新启动 Linux?

    我有一个 Qt 4 GUI 我需要在下拉菜单中提供一个选项 允许用户选择重新启动计算机 我意识到这对于以其他方式重新启动计算机的能力来说似乎是多余的 但选择需要保留在那里 我尝试使用 system 来调用以下内容 suid root she
  • Linux无法删除文件

    当我找到文件时 我在删除它们时遇到问题 任务 必须找到带有空格的文件并将其删除 我的尝试 rm find L root grep i 但我有错误 rm cannot remove root test No such file or dire
  • 如何在不使用 IDE 的情况下在 Linux 上运行 Java 项目

    我是 Java 新手 基本上 我开发了一个java项目 其中包含Eclipse中的多个Java包 该项目在我安装了 redhat Linux 的桌面上运行正常 然而 我需要在一个更强大的没有安装X11的Linux服务器 redhat ent
  • Linux 中 m 标志和 o 标志将存储在哪里

    我想知道最近收到的路由器通告的 m 标志和 o 标志的值 从内核源代码中我知道存储了 m 标志和 o 标志 Remember the managed otherconf flags from most recently received R
  • 有没有一种快速方法可以从 Jar/war 中删除文件,而无需提取 jar 并重新创建它?

    所以我需要从 jar war 文件中删除一个文件 我希望有类似 jar d myjar jar file I donot need txt 的内容 但现在我能看到从 Linux 命令行执行此操作的唯一方法 不使用 WinRAR Winzip
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 如何使用 JSch 将多行命令输出存储到变量中

    所以 我有一段很好的代码 我很难理解 它允许我向我的服务器发送命令 并获得一行响应 该代码有效 但我想从服务器返回多行 主要类是 JSch jSch new JSch MyUserInfo ui new MyUserInfo String
  • FileOutputStream.close() 中的设备 ioctl 不合适

    我有一些代码可以使用以下命令将一些首选项保存到文件中FileOutputStream 这是我已经写了一千遍的标准代码 FileOutputStream out new FileOutputStream file try BufferedOu
  • 在 C 中使用单个消息队列是否可以实现双向通信

    我希望服务器向客户端发送一些消息 并让客户端确认它 我被分配了这个任务 我可以在 C linux 中使用单个消息队列来完成它还是我需要创建两个 谢谢 是的 可以使用 sysV 消息队列来做到这一点 从您之前的问题来看 您正在使用该队列 您可
  • linux下无法创建僵尸进程

    嗯 我有一个奇怪的问题 我无法在我的项目中创建僵尸进程 但我可以在其他文件中创建僵尸进程 有简单的说明 int main if fork 0 printf Some instructions n else sleep 10 wait 0 r
  • 调用 printf 系统子例程在汇编代码中输出整数错误[重复]

    这个问题在这里已经有答案了 来回 在windows7控制台窗口中运行gcc s2 asm 然后生成一个exe文件 运行a exe 然后崩溃 为什么 s2 asm 代码由以下源代码生成 int m m 1 iprint m s2 asm请参考
  • python获取上传/下载速度

    我想在我的计算机上监控上传和下载速度 一个名为 conky 的程序已经在 conky conf 中执行了以下操作 Connection quality alignr wireless link qual perc wlan0 downspe
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • 无需超级用户即可在 Linux 中打开 RAW 套接字

    我必须编写一个在 Linux 上运行的 ping 函数 语言是 C 所以 C 也可以 在网上搜索并查看源代码ping命令 事实证明我应该创建一个原始套接字 icmp sock socket AF INET SOCK RAW IPPROTO
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include

随机推荐

  • android环境配置

    JDK配置 JRE问题 Windows 打开PowerShell 进入JDK目录 执行 bin jlink exe module path jmods add modules java desktop output jre 环境变量 系统环
  • [STM32F10x] 利用定时器测量脉冲宽度

    硬件 STM32F103C8T6 平台 ARM MDk V5 11 前面一篇文章讲过如何利用定时器测量信号的频率 见 STM32F10x 利用定时器测量频率 使用的是定时器的捕获 比较单元 Capture compare 它也可以测量输入信
  • JDBC中的几个常见问题

    JDBC中的几个常见问题 1 JDBC中的Statement和PreparedStatement CallableStatement的区别 2 JDBC中大数据量分页的解决方法 3 事务 4 execute executeQuery exe
  • VS Code 格式化后 自动让函数名后有空格

    fetchCommentCount 像这样fetchCommentCount和 之间有空格 这是我们的目标 return 只需要在Vscode设置文件Settings中加入以下两句 vetur format defaultFormatter
  • 使用yum命令不能安装mysql的问题(No package mysql-server available. Error: Nothing to do)

    问题 这是因为本地yum仓库中没有对应的mysql包 所以在安装之前先要配置rpm包 这里使用的是mysql5 7的rpm rpm ivh https repo mysql com mysql57 community release el7
  • char类型的大小范围

    要知道char类型的大小范围 首先要知道char类型占1个字节 而1个字节等于8个bit位 每一个bit位是一位二进制数 所以char类型有8个二进制位 那么就有2的8次方256种可能 我们先讨论 signed char 有符号 首位是符号
  • IOS键盘的相关设置(UITextfield)

    http blog sina com cn s blog 7018d3820101djut html 一 键盘风格 UIKit框架支持8种风格键盘 typedef enum UIKeyboardTypeDefault 默认键盘 支持所有字符
  • Java基础笔记(初学者适用)

    目录 一 Java主函数解析 二 Java学习注意事项 三 JDK和JRE的区别 1 jdk 开发环境 核心 2 jre 运行环境 3 JVM 转换环境 四 常见转义字符 五 变量 1 变量介绍 2 变量细节 3 作用域 4 数据类型 1
  • 粤嵌实训(笔记)

    目录 1 LCD换自己喜欢的颜色 2 LCD换个图案 3 LCD换张图片 4 网线登录 ifconfig eth0 192 168 5 9 5 触屏电子相册 6 网络编程 TCP通信 7 网络编程 UDP通信 8 开发板串口通信MCU 32
  • 二叉树与二叉搜索树的理解

    树 tree 是一种抽象数据类型 ADT 用来模拟具有树状结构性质 它是由n n 0 个有限节点通过连接它们的边组成具有层次关系的集合 把它叫做树是因为它看起来像一棵倒挂的树 也就是说它是根朝上 而叶朝下的 树由多种 一个节点有两个以上子节
  • 快速训练ai作画模型的python代码

    感谢你的问题 如果你想快速训练一个 AI 作画模型 你可以使用开源的深度学习框架 例如 TensorFlow PyTorch 或 Keras 这里是一个基于 TensorFlow 的示例代码 它使用了一种叫做 CycleGAN 的生成对抗网
  • 使用 ESP-Prog / Jlink 进行 JTAG 调试时的常见错误及解决办法

    此篇博客用来记录使用 ESP PROG Jlink 来对 ESP32 Lyrat 进行 JTAG 调试时遇到的一些问题以及解决办法 如果对进行 JTAG 相关操作有疑惑 请参考以下资料 使用 ESP Prog 进行 JTAG 调试 使用 J
  • openmediavault配置文件共享

    OpenMediaVault是一个基于Debian的专用Linux发行版 用于构建网络连接存储 NAS 系统 它提供了一个易于使用的基于Web的界面 多语言支持 卷管理 监控和插件系统 以通过LDAP Bittorrent和iSCSI功能进
  • 多维时序

    多维时序 MATLAB实现RBF径向基神经网络多变量时间序列未来多步预测 目录 多维时序 MATLAB实现RBF径向基神经网络多变量时间序列未来多步预测 预测效果 基本介绍 模型描述 程序设计 参考资料 预测效果 基本介绍 MATLAB实现
  • 你会使用GROUP BY吗?

    职业开始前两年 发现面试特别喜欢问SQL的问题 觉得不够高大上 觉得没有框架什么的高大上 但是当你处理实际的业务问题 发现SQL是避免不了的 SQL可以帮你解决一些你在代码上处理逻辑很麻烦的地方 即时现在有mybatis插件 可以不用写SQ
  • Stable Diffusion下载完身体有点吃不消(内附秋叶集合安装包)

    大家好 今天我来介绍一款令人惊叹的开源软件 Stable Diffusion 这是一款基于AI技术的图片生成软件 可以让用户轻松随心所欲地创建出各种令人惊叹的图片 在这里插入图片描述 Stable Diffusion拥有强大的AI算法 不管
  • 一文看懂随机森林 - Random Forest(附 4 个构造步骤+10 个优缺点)

    本文首发自 产品经理的人工智能知识库 原文地址 一文看懂随机森林 Random Forest 附 4 个构造步骤 10 个优缺点 随机森林是一种由决策树构成的集成算法 他在很多情况下都能有不错的表现 本文将介绍随机森林的基本概念 4 个构造
  • 外包公司“混”了2年,我只认真做了5件事,如今顺利拿到阿里 Offer。

    前言 是的 我一家外包公司工作了整整两年时间 在入职这家公司前 也就是两年前 我就开始规划了我自己的人生 所以在两年时间里 我并未懈怠 现如今 我已经跳槽到了阿里 顺利拿下 offer 自己的情况很普通 本科文凭 没有背景 分享这次我的经历
  • gd32f103 adc通道说明

    file main c brief ADC Temperature Vrefint demo Copyright 2017 GigaDevice 2017 06 23 V1 0 0 demo for GD32F30x include gd3
  • 深入理解Netty底层基础、中断、NIO、epoll~~~~

    深入理解Netty底层基础 LInux 操作系统中断 什么是系统中断 这个没啥可说的 大家都知道 CPU 在执行任务途中接收到中断请求 需要保存现场后去处理中断请求 保存现场称为中断处理程序 处理中断请求也就是唤醒对应的任务进程来持有CPU