文件IO、IO流、NIO、netty(poll、selector、epoll)
2021-08-13 11:47:13 0 举报
文件IO和IO
作者其他创作
大纲/内容
netstat -natp 0.0.0.0:8090 0.0.0.0:* LISTEN-----------------------------0.0.0.0:8090 0.0.0.0:* ESTABLISHMENT
线性地址-进程
stack
以上图示:是以client为断开发起方的状态,如果是Server发起断开,那么也会出现这些状态
BIO的弊端阻塞 BLOCKING
这个是VIP课!!系统IO原理:linuxVFS FDpagecache【java】1文件系统的io2内存和io关系3网络io
keepalive
c
TCP分手
APP Serversocket -> fd4bindlisten fd4
pc4k
你不能控制的
网络IO 变化 模型 BIO
优势:通过1个或几个线程,来解决N个IO连接的处理问题:C10K每循环一次:O(n)复杂度recv 很多调用是无意义的,浪费的,调用:计组:系统调用*read 无罪 无效的无用的read别调起
性能稍高一些
192.168.150.11 9090
资源
Poll和Epoll底层实现
TCP 如果双方建立了连接很久都不说话?对方还活着吗?
data
select(fds)poll(fds)
syn
limit
APP
APPwhile(100000)三次握手
txtcode10*4KB1
VM
C100_123P+S200_80P
表:中断向量表25580 cb
app1-x
Servermainwhileaccept 系统调用
EPOLL规避的遍历
有可能最后的ack没有到达对方,自己多留一会资源
网卡
重复调起send-queue
1
out
appX
BUFFER
APP server
AIP_CPORT+XIP_XPORT : FD3AIP_BPORT+XIP_XPORT : FD4AIP_APORT+XIP_XPORT : FD5进程隔离AIP_CPORT+XIP_YPORT : FD3AIP_BPORT+XIP_YPORT : FD4AIP_APORT+XIP_YPORT : FD5
ooxx
IO设备
clonerecv(fd5--> /blocking
www.github.com/bjmashibing
close_wait
DMA
不走寄存器,走DMA
fd9
lsof -pnetstat -natp tcpdump
IO
on heap
Client300,123
app
CAIPCPORT:123
C300_123P+S200_80P
off heap
OS:EPOLLfont color=\"#ff0000\
kernel
面试题
为啥ulimit -n 1024但是连接数超过了1024呢?我查查在告诉你们哈
allocateDirect
内存
根据给出的fd
C
select
int 0x80
page4kB不会全量分配缺页内存优化
APP Serversocket -> fd4bindlisten fd4epoll_createepoll_ctl epoll_wait ->fdsacceptrecv
S
native维护一个集合
cpummu
192.168.150.1 + 10000 192.168.150.11 9090
两处阻塞:1. accept2. recv解决方法:抛出线程来解决 -> 阻塞2
文件
SELECT(FDS)POLL
int : cpu的指令
kernel《深入理解linux内核》《深入理解计算机系统》epoll < 怎么知道数据到达中断
硬件
app1保护现场可运行
目的:192.168.110.100 + 10000 192.168.150.2 19090
cpu
client
内核底层
thread
服务端 serversocket0.0.0.0:0 0.0.0.0:80 L
FD4buffer
多路复用器:select poll的弊端,问题1,每次都要重新,重复传递fds (内核开辟空间)2,每次,内核被调了之后,针对这次调用,触发一个遍历fds全量的复杂度
windows
链表FD4
SELECT POSIXPOLL EPOLL kqueue
app1fd指针 seek 20
clone(
Thread
FIN_ACK
NIO
heap
FD1 READ重复调起
多 路 复用器
FileChannel
MMU
多条 路(IO) 通过一个系统调用,获得其中的IO状态然后,由程序自己对着有状态的IO 进行R/W
在TIME_WAIT没有结束前,内核中的socket的四元组被占用,相同的对端不能使用这个资源建立新的连接浪费的是名额!站着茅坑不拉屎这个不是DDOS
内核级开辟资源
app1-z
物理网络
Object
main_thread
1,package2,buffer3,轮询
SO,所以,程序只要调用wait,能及时取走有状态fd的结果集
ByteBuffer
read(fd8)
3 mod dirty
cap
2
netstat -natp 0.0.0.0:8090 0.0.0.0:* LISTEN
FIN
-:普通文件(可执行,图片,文本)REGd: 目录l:连接b:块设备c:字符设备 CHRs:socketp: pipeline[eventpoll]:。。。
内核中,程序在红黑树中放过一些FD,那么伴随内核基于中断处理完fd的buffer,状态呀,之后,继续把有状态的fd,copy到链表中
进程调度活跃
文件类型
WRITEHANDLER
map
fd8
中断
唯一性
EPOLL V.S SELECT/POLL
appwhile(){select(fds) O(1)recv(fd O(m)
PUT()不会产生系统调用
page cache优化IO性能丢失数据
FD1.register selector OP_WRITE
物理地址内存
channel.readchannel.write
目的:192.168.110.100 + 10000 192.168.150.11 9090
buffer
select()
selectkeys()
TCP
ACK
FD1FD2
yum install man man-pagesman 2 select
192.168.150.0
pos
Linux
强行插入
90
硬盘file:appW 10*4kB
多个进程
txt
selector
ack
CLIENT
内核级的
pagecache
fdseek
java Clinux pro
硬盘
FD22
目的:192.168.150.1 + 10000 192.168.150.11 9090
物理内存
FIN_WAIT2
磁盘4K
四元组(CIP_CPORT+SIP_SPORT)
延伸
三次握手 四次分手
epoll_wait == select
PageCachekernel 折中方案
即便你不调用accept
我们为啥提出这个模型?考虑资源利用,充分利用cpu核数考虑有一个fd执行耗时,在一个线性里会阻塞后续FD的处理当有N个fd有R/W处理的时候:将N个FD 分组,每一组一个selector,将一个selector压到一个线程上最好的线程数量是:cpu cpu*2其实但看一个线程:里面有一个selector,有一部分FD,且他们是线性的多个线程,他们在自己的cpu上执行,代表会有多个selector在并行,且线程内是线性的,最终是并行的fd被处理但是,你得明白,还是一个selector中的fd要放到不同的线程并行,从而造成canel调用嘛? 不需要了!!!上边的逻辑其实就是分治,我的程序如果有100W个连接,如果有4个线程(selector),每个线程处理 250000那么,可不可以拿出一个线程的selector就只关注accpet ,然后把接受的客户端的FD,分配给其他线程的selector
kernel:内核VFS 树:虚拟文件系统FD:文件描述符inode idpagecache 4kdirty 脏flush
TIME_WAIT2MSL30 1 2
Client100,123
READ HADNLER
消耗不消耗资源消耗SOCKET四元组规则
key.canel
2 del dirtyDMA协处理器(释放CPU)
保护现场切换用户态内核态
面向连接的,可靠的传输协议
appW
BIO的弊端1. accept会走一次内核产生一次系统调用2. clone也会走一次内核产生一次系统调用,还需要创建线程3. 线程创建的越多,线程的切换也会造成大量的资源消耗
3root/boot/dev/etc
File ifile = new File(\"/ooxx.txt\")out (fd) = new outputstream(ifile)out.write(\"fdsfsdf\")
ooxxdirty
kernelpc
-Xmx1Gjvm heap
缓冲区
同步异步阻塞非阻塞strace -ff -o out cmd马老师讲的计组
JAVA
Mappedmmap()逻辑地址
管道的左右两边各开启一个进程
pagecachedirty
三次握手
192.168.110.100 + 10000 192.168.150.11 9090
syn+ack
3次握手
站在程序的角度什么时候调用select内核什么时候遍历fds修正状态
受内核映像
closed
app2-y
I/O
epoll_create-> fd6
s
app1-y
C10K
这个理论是对的,只不过要看用户,而且,公司里,生产环境肯定是非root用户启动程序
system callint(80)
ooxx[cache]
JDK new io
冯诺依曼计算器,控制器主存储器输入输出设备 I/O
allocate
不传递fds不触发内核遍历
数据包多大数据包大小:MTU数据内容大小:MSS
IO中断
/proc 映射的是内核里面变量属性,也包含一些进程ID号/proc/$$$$ $BASHPID 当前bash的pid /proc/$$/fd 命令lsof -op $$ 当前程序下所有文件描述符重定向:不是命令,机制输入,输出 I/O<>管道 | 读文件的第8行:head -8 file.txt | tail -1
目录树结构趋向于稳定有一个映射的过程
ThreadFD1.READ()
BIO
OS 没有觉得数据可靠性为什么设计pagecache ,减少 硬件 IO 调用,提速,优先使用内存即便你想要可靠性,调成最慢的方式但是单点问题会让你的性能损耗,一毛钱收益都没有主从复制,主备HAkafka/ES 副本(socket io) (同步/异步)。。。
page cache内核维护 中间层使用多大内存是否淘汰是否延时,是否丢数据
192.168.150.1
192.168.150.2vm-nat service
寄存器
app2fd 指针 seek 8
是你能控制的
table 1~10 -》30-4080 -》 222访问80 异常 缺页
在主线程里不能阻塞执行,不能是线性的所以事件会被重复触发解决方案key.cancel
1create dirty
抽象一切皆文件
linux : heapJAVA进程
任何程序都有0:标准输入1:标准输出2:报错输出
socket
FD6
SXIPXPORT:80YPORT:9090
磁盘
/boot/dev/loop0/mnt/ooxx
协处理器DMA
计组:中断处理延伸:
循环遍历
线性地址
同一套代码: java NIO selector:pollepoll的不同底层实现
app 200 80
2swap2G
epoll_wait
1G
鼠标dpi100016000
fd6<红黑树>FD4 -> accept
OS NONBLOCKINIG
app2
mydisk.img
服务端是否需要为client的连接分配一个随机端口号?不需要
用塞控制客户端和服务端建立的连接,会有一个窗口大小的概念(wink),这时候如果发送的包大于该窗口,则服务端回复的ack里面会告诉客户端窗口满了,这时客户端就会阻塞不继续发送数据包,直到服务端通知可以发送
时钟中断硬中断晶振
软中断陷阱int 80
CPU
SELECTsynchronous I/O multiplexingFD_SETSIZE (1024)POLL里面没有1024的限制
即便你不调用我内核,我内核也会随着中断完成所有FD的状态设置
中断描述符表012128 call back方法255
客户端内核
0x80: 1281000 0000值寄存器
网络IO 变化 模型 NIO
192.168.110.100
CPUint
dma
pagecache1个
服务端内核
txt1个
网络IO: TCP 参数
键盘
只要程序自己读写,那么,你的IO模型就是同步的
0 条评论
下一页