NIO学习笔记,从Linux IO演化模型到Netty—— 从BIO到epoll模型
本文不涉及具体代码,只分析Linux IO演化的心路历程,学习资料来源网络,不保证一定正确,若有错误,欢迎指出。
BIO
服务端创建socket(80端口),文件描述符3号。
当线程调用accept时,阻塞等待3 fd连接就绪。
网卡(80端口)收到数据,将数据写入内存,向cpu发出中断信号,内核得知3 fd有新数据,cpu调用中断程序响应中断。
线程唤醒,文件描述符为4号的socket,这时候就要新建线程T1去循环read(阻塞) 4fd了,因为主线程要负责连接。
弊端:一个线程处理一个连接,当有大量短连接的时候,就会有大量线程新建和消亡,频繁地状态切换,耗费大量资源。不过适用于长连接,且每个连接有大量数据交互的情况。
是不是可以让一个线程去处理多个连接呢?这样的入口点在哪里呢?
答曰:在read非阻塞,线程read 4fd,没有数据,那就去read 5fd,这样循环遍历。
于是有了非阻塞式IO
现在是可以一个线程处理多个连接了,但是又出现了新的问题。
1.当有大量有效连接时(指由数据要交互),一个线程要read 4fd,接着read 5fd,这样处理不及时。
2.当有大量无效连接时,一个线程频繁的read(系统调用),意味着要频繁的从用户态切换到内核态,这也耗费大量资源。
是不是可以减少read的调用次数呢?等到真的有数据来的时候再read。
于是有了IO多路复用的select模型
线程调用select,把要监听的socket和对应的期待事件告诉内核,然后阻塞在所有的fd上,当内核发现有事件发生时,再唤醒对应fd上的线程,而后线程就可以去read。
但是,线程只知道监听的所有socket上,某些有数据,却不知道是哪个,所以要挨个遍历(每个socket是非阻塞的)。当有大量无效连接时,这一轮当中依然有 很多无效的read。
处理完一轮之后,进入到下一轮的select,而每一轮的select都要把要监听的socket的fd传给内核,数目一大,这成本也很高。
基于这两方面原因,select的上限设定为1024。(poll模型基本与select一样,只是有少量改进,如不限数量(仍然受限于物理),将略过)
其实fd传一次就够了吧?以后的每一次都是在上一次的基础上,要新增就新增,要减掉就减掉,否则要监听还是和上一次一样。
是不是可以省去无效的read呢?要是我醒来之后,要read的每一个socket都是有效的就好了!
于是有了IO多路复用的epoll模型
epoll_create()得到一个5号epfd指向的是一个mmap共享空间(有关mmap,零拷贝的内容在下一篇讲解)。
接着得到一个7号fd的socket(NONBLOCK),通过epoll_ctl将它加到5号epfd的红黑树上。以后每一次要加,就通过调用这个函数加,文件描述符只用传一次。
epoll_wait(5)线程在eventpoll上阻塞等待(可以设置超时参数)。
当数据到来,5 epfd的红黑树上有事件发生时,中断程序将会把发生事件的socket加到rdlist这个双向链表中,然后唤醒5 epfd中eventpoll等待队列中的线程。
线程唤醒后就可以有效地遍历双向链表了。
epoll_wait的时候设置水平触发或者边缘触发
event.events = EPOLLIN | EPOLLET;//边缘触发,当有新数据到来时触发,若上一次没有读完,需等到下一次有新数据来。Netty中为边缘触发
event.events = EPOLLIN; // LT是默认模式,当socket中有数据(可能是上一次遗留),epoll_wait即可返回。jdk nio中为水平触发
NIO学习笔记,从Linux IO演化模型到Netty—— 从BIO到epoll模型的更多相关文章
- NIO学习笔记,从Linux IO演化模型到Netty—— Linux零拷贝
这里只是感性地认识Linux零拷贝,不涉及具体细节. 1.Linux传统的数据拷贝 用户进程是不能直接访问文件系统的,要先切换到内核态,发起系统调用,DMA把磁盘中的数据写入内核空间,内核再把数据拷贝 ...
- NIO学习笔记,从Linux IO演化模型到Netty—— Java NIO零拷贝
同样只是大致上的认识. 其中,当使用transferFrom,transferTo的时候用的sendfile(). 如果系统内核不支持 sendfile,进一步执行 transferToTrusted ...
- NIO学习笔记,从Linux IO演化模型到Netty—— 究竟如何理解同步、异步、阻塞、非阻塞
我的观点 首先,分开各自理解. 1. 同步:描述两个(或者多个)个体之间的协调关系. 比如,单线程中,methodA调用了methodB,methodB返回后,methodA才往下执行,那么称A同步调 ...
- NIO学习笔记,从Linux IO演化模型到Netty—— Netty零拷贝
Netty的中零拷贝与上述零拷贝是不一样的,它并不是系统层面上的零拷贝,只是相对于ByteBuf而言的,更多的是偏向于数据操作优化这样的概念. Netty中的零拷贝: 1.CompositeByteB ...
- Java NIO 学习笔记(七)----NIO/IO 的对比和总结
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- 零拷贝详解 Java NIO学习笔记四(零拷贝详解)
转 https://blog.csdn.net/u013096088/article/details/79122671 Java NIO学习笔记四(零拷贝详解) 2018年01月21日 20:20:5 ...
- Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- Java:NIO 学习笔记-1
Java:NIO 学习笔记-1 说明:本笔记是根据bilibili上 尚硅谷 的课程 NIO视频 而做的笔记 主要内容 Java NIO 简介 Java NIO 与 IO 的主要区别 缓冲区(Buff ...
- Java NIO学习笔记
Java NIO学习笔记 一 基本概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成. 所有语言运行时系统提供执 ...
随机推荐
- Linux/UNIX编程:获取指定用户所有正在运行的进程ID和进程名
先用系统函数 `getpwnam` 获得指定用户名的 UID,然后遍历 /proc/ 中所有 PID 目录,如果 /proc/PID/status 中的 UID 是输入用户名对应的 UID 则输出该 ...
- 记一个实时Linux的中断线程化问题
背景 有一个项目对实时性要求比较高,于是在linux内核上打了RT_PREEMPT补丁. 最终碰到的一个问题是,芯片本身性能不强,CPU资源不足,急需优化. 初步分析 看了下cpu占用率,除了主应用之 ...
- sqlserver partitition and partition table --- partition show
I can not believe that I had done this about two years Now we know there is totally different betwee ...
- 题解【Luogu P6102 谔运算】
\[ \texttt{Description} \] 给出一个长度为 \(n\) 的数列 \(a\),求 \(\sum\limits_{i=1}\limits^{n}\sum\limits_{j=1} ...
- css 浏览兼容问题及解决办法 (1)
主流浏览器css兼容问题的总结 最近又搞了一波网站的兼容,由于要求ie浏览器还是要兼容到ie8,所以调起来还是各种蛋疼. 现在就post一些做兼容的总结,可能不够全面,但是可以告诉大家如何避过一些坑. ...
- TCP、UDP 协议的区别
TCP 面向连接 可靠 传输形式:字节流 传输效率:慢 所需资源:多 首部字节:20-60 应用场景:要求通讯数据可靠(如文件传输.邮件传输) UPD 无连接 不可靠 传输形式:数据报文段 传输效率: ...
- Django ORM各种查询
正向和反向查询 正向 ----> 关联字段在当前表中,从当前表向外查叫正向 反向 —> 关联字段不在当前表中,当当前表向外查叫反向 正向通过字段,反向通过表名查 表结构 from djan ...
- Go语言实现:【剑指offer】调整数组顺序使奇数位于偶数前面
该题目来源于牛客网<剑指offer>专题. 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和 ...
- eclipse里新建work set,将项目分组放在不同文件夹
想必大家的Eclipse里也会有这么多得工程...... 每次工作使用到的项目肯定不会太多...... 每次从这么大数量的工程当中找到自己要使用的, 必须大规模的滚动滚动条......有点不和谐了. ...
- 异步并发利器:实际项目中使用CompletionService提升系统性能的一次实践
场景 随着互联网应用的深入,很多传统行业也都需要接入到互联网.我们公司也是这样,保险核心需要和很多保险中介对接,比如阿里.京东等等.这些公司对于接口服务的性能有些比较高的要求,传统的核心无法满足要求, ...